Skip to content

Commit

Permalink
feat: improves PDP multiple template order: slug with sku, without sk…
Browse files Browse the repository at this point in the history
…u, category tree
  • Loading branch information
eduardoformiga committed May 20, 2024
1 parent e3520da commit f237897
Show file tree
Hide file tree
Showing 2 changed files with 122 additions and 13 deletions.
58 changes: 47 additions & 11 deletions packages/core/src/utils/multipleTemplates.ts
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,16 @@ export function normalizePDPTemplate(templateValue: string) {
return formattedValue.toLowerCase()
}

// Returns the slug without the skuId at the end ("-{number}/p") if it matches the pattern "-{number}-{skuId}/p", otherwise returns the slug as is.
const getSlugWithoutSkuIdFromPDP = (slug: string) => {
const match = slug.match(/-(\d+)-(\d+)\/p$/) // Matches the pattern "-{number}-{skuId}/p" at the end of the slug
if (match) {
const newSlug = slug.replace(`-${match[2]}/p`, '/p') // Replace the last number (skuId) before '/p'
return newSlug
}
return slug
}

/**
* Find the best PDP template from the CMS based on the slug or in the product category tree.
* Prioritizing the following order:
Expand All @@ -155,24 +165,50 @@ export function findBestPDPTemplate(
slug: string,
product: ServerProductQueryQuery['product']
) {
// productSlugAndCategoryTree with the prioritized order. [slug, subcategory tree, category tree, department]
const productSlugAndCategoryTree = product?.breadcrumbList?.itemListElement
? [...product?.breadcrumbList?.itemListElement]
.reverse()
.map(({ item }) => item)
: []
productSlugAndCategoryTree.unshift(slug)

for (const item of productSlugAndCategoryTree) {
const templateValues = getPDPTemplateValues({
slug,
itemListElement: product?.breadcrumbList?.itemListElement ?? [],
})

for (const template of templateValues) {
for (const page of pages) {
if (!page.settings?.template?.value) continue

const templateValue = normalizePDPTemplate(page.settings.template.value)
if (templateValue === item) {
const templateValueFromCms = normalizePDPTemplate(
page.settings.template.value
)
if (templateValueFromCms === template) {
return page
}
}
}

return pages.find((page) => !page.settings?.template?.value) || pages[0]
}

export function getPDPTemplateValues({
slug,
itemListElement = [],
}: {
slug: string
itemListElement: ServerProductQueryQuery['product']['breadcrumbList']['itemListElement']
}) {
// productSlugAndCategoryTree with the prioritized order. [link-skuId/p, subcategory tree, category tree, department]
const productSlugAndCategoryTree = [...itemListElement]
.reverse()
.map(({ item }) => item)

// PDP slug comes from FastStore API with the format `${link}-${skuId}/p`, the most specific for multiple page templates,
// so it should be the first element
const slugWithSkuId = productSlugAndCategoryTree?.[0] ?? slug

// PDP slug without skuId `${link}/p`, should be the second element
const slugWithoutSkuId = getSlugWithoutSkuIdFromPDP(slug)

// removes duplicated and undefined
return [
slugWithSkuId,
slugWithoutSkuId,
...productSlugAndCategoryTree.slice(1),
].filter((item, index, arr) => item && arr.indexOf(item) === index)
}
77 changes: 75 additions & 2 deletions packages/core/test/utils/multipleTemplates.test.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,28 @@
import type { Rewrite, RewritesConfig } from '../../src/utils/multipleTemplates'
import { hasRewritesConfigForSlug } from '../../src/utils/multipleTemplates'
import {
getPDPTemplateValues,
hasRewritesConfigForSlug,
} from '../../src/utils/multipleTemplates'

const productItemListElementMock = [
{ item: '/department/', name: 'test', position: 1 }, // Department
{ item: '/department/category/', name: 'test', position: 1 }, // Category tree
{ item: '/department/category/subcategory/', name: 'test', position: 1 }, // Subcategory tree
{
item: '/department/category/subcategory/subcategory2/',
name: 'test',
position: 1,
}, // Subcategory tree tree
{
item: '/department/category/subcategory/subcategory2/subcategory3/',
name: 'test',
position: 1,
}, // Subcategory tree
{ item: '/slug-product-test-111111-2222/p', name: 'test', position: 1 }, // PDP slug with skuId
]

describe('Multiple page templates', () => {
describe('hasRewritesConfigForSlug', () => {
describe('PLP hasRewritesConfigForSlug', () => {
it('should return true when rewrites is an array of objects containing the desired destination and source', () => {
const rewritesArr: Rewrite[] = [
{ source: '/test/my-office', destination: '/office' },
Expand Down Expand Up @@ -63,4 +83,57 @@ describe('Multiple page templates', () => {
expect(result).toBe(false)
})
})

describe('PDP getPDPTemplateValues', () => {
it('should return correct template values when PDP slug has skuId', () => {
const result = getPDPTemplateValues({
slug: '/slug-product-test-111111-2222/p',
itemListElement: productItemListElementMock,
})
expect(result).toEqual([
'/slug-product-test-111111-2222/p', // PDP slug with skuId
'/slug-product-test-111111/p', // PDP slug without skuId
'/department/category/subcategory/subcategory2/subcategory3/', // Subcategory tree
'/department/category/subcategory/subcategory2/', // Subcategory tree
'/department/category/subcategory/', // Subcategory
'/department/category/', // Category
'/department/', // Department
])
})

it('should return correct template values when PDP slug does not have skuId', () => {
const result = getPDPTemplateValues({
slug: '/slug-product-test-111111/p',
itemListElement: productItemListElementMock,
})
expect(result).toEqual([
'/slug-product-test-111111-2222/p', // PDP slug with skuId
'/slug-product-test-111111/p', // PDP slug without skuId
'/department/category/subcategory/subcategory2/subcategory3/', // Subcategory tree
'/department/category/subcategory/subcategory2/', // Subcategory tree
'/department/category/subcategory/', // Subcategory
'/department/category/', // Category
'/department/', // Department
])
})

it('should return the PDPs slugs with and without skuId when itemListElement is undefined and slug has skuId', () => {
const result = getPDPTemplateValues({
slug: '/slug-product-test-111111-2222/p',
itemListElement: undefined,
})
expect(result).toEqual([
'/slug-product-test-111111-2222/p',
'/slug-product-test-111111/p',
])
})

it('should return the PDPs slug with skuId when itemListElement is undefined and slug do not have skuId', () => {
const result = getPDPTemplateValues({
slug: '/slug-product-test-111111/p',
itemListElement: undefined,
})
expect(result).toEqual(['/slug-product-test-111111/p'])
})
})
})

0 comments on commit f237897

Please sign in to comment.