Skip to content

Commit

Permalink
feat: product-links block
Browse files Browse the repository at this point in the history
  • Loading branch information
maxakuru committed Nov 21, 2024
1 parent 116ee55 commit 7980da2
Show file tree
Hide file tree
Showing 5 changed files with 69 additions and 31 deletions.
11 changes: 10 additions & 1 deletion src/content/queries/cs-product.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,11 @@ export const adapter = (config, productData) => {
addToCartAllowed: productData.addToCartAllowed,
inStock: productData.inStock,
externalId: productData.externalId,
links: (productData.links ?? []).map((l) => ({
sku: l.product.sku,
urlKey: l.product.urlKey,
types: l.types,
})),
images: forceImagesHTTPS(productData.images) ?? [],
attributes: productData.attributes ?? [],
attributeMap: Object.fromEntries((productData.attributes ?? [])
Expand Down Expand Up @@ -145,7 +150,11 @@ export default ({ sku, imageRoles = [], linkTypes = [] }) => gql`{
label
}
links(linkTypes: [${linkTypes.map((s) => `"${s}"`).join(',')}]) {
product {
sku
urlKey
}
linkTypes
}
attributes(roles: ["visible_in_pdp"]) {
name
Expand Down
30 changes: 28 additions & 2 deletions src/templates/html/HTMLTemplate.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@ export class HTMLTemplate {
/** @type {Image} */
image = undefined;

/** @type {import('../json/JSONTemplate.js').JSONTemplate} */
jsonTemplate = undefined;

/**
* @param {Context} ctx
* @param {Product} product
Expand All @@ -69,6 +72,7 @@ export class HTMLTemplate {
this.product = product;
this.variants = variants;
this.image = findProductImage(product, variants);
this.jsonTemplate = jsonTemplateFromContext(this.ctx, this.product, this.variants);
}

/**
Expand Down Expand Up @@ -149,10 +153,9 @@ ${HTMLTemplate.metaProperty('product:price.currency', product.prices.final.curre
* @returns {string}
*/
renderJSONLD() {
const jsonTemplate = jsonTemplateFromContext(this.ctx, this.product, this.variants);
return /* html */ `\
<script type="application/ld+json">
${jsonTemplate.render()}
${this.jsonTemplate.render()}
</script>`;
}

Expand Down Expand Up @@ -330,6 +333,28 @@ ${this.variants?.map((v) => /* html */`\
</div>`;
}

/**
* @returns {string}
*/
renderProductLinks() {
const { links } = this.product;
if (!links) {
return '';
}
return /* html */ `\
<div class="product-links">
${links.map((link) => {
const url = this.jsonTemplate.constructProductURL(undefined, link);
return /* html */`\
<div>
<div>${link.sku}</div>
<div><a href="${url}">${url}</a></div>
<div>${(link.types ?? []).join(', ')}</div>
</div>`;
}).join('\n')
}`;
}

/**
* @returns {string}
*/
Expand Down Expand Up @@ -357,6 +382,7 @@ ${HTMLTemplate.indent(this.renderProductAttributes(attributes), 8)}
${HTMLTemplate.indent(this.renderProductOptions(options), 8)}
${HTMLTemplate.indent(this.renderProductVariants(), 8)}
${HTMLTemplate.indent(this.renderProductVariantsAttributes(), 8)}
${HTMLTemplate.indent(this.renderProductLinks(), 8)}
</div>
</main>
<footer></footer>
Expand Down
32 changes: 15 additions & 17 deletions src/templates/json/JSONTemplate.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,12 @@ export class JSONTemplate {

/**
* @param {Variant} [variant]
* @returns
* @param {Pick<Product, 'sku'|'urlKey'>} [pproduct]
* @returns {string}
*/
constructProductURL(variant) {
const {
product,
ctx: { config },
} = this;
constructProductURL(variant, pproduct) {
const product = pproduct || this.product;
const { ctx: { config } } = this;
const { host, matchedPatterns, confMap } = config;
const matchedPathConfig = confMap?.[matchedPatterns[0]];

Expand All @@ -52,20 +51,19 @@ export class JSONTemplate {
.replace('{{sku}}', encodeURIComponent(product.sku.toLowerCase()));

const productUrl = `${host}${productPath}`;
if (!variant) {
return productUrl;
}

if (variant) {
const offerVariantURLTemplate = matchedPathConfig?.offerVariantURLTemplate;
if (!offerVariantURLTemplate) {
return `${productUrl}?optionsUIDs=${encodeURIComponent(variant.selections.join(','))}`;
}

const variantPath = offerVariantURLTemplate
.replace('{{urlkey}}', product.urlKey)
.replace('{{sku}}', encodeURIComponent(variant.sku));
return `${host}${variantPath}`;
const offerVariantURLTemplate = matchedPathConfig?.offerVariantURLTemplate;
if (!offerVariantURLTemplate) {
return `${productUrl}?optionsUIDs=${encodeURIComponent(variant.selections.join(','))}`;
}

return productUrl;
const variantPath = offerVariantURLTemplate
.replace('{{urlkey}}', product.urlKey)
.replace('{{sku}}', encodeURIComponent(variant.sku));
return `${host}${variantPath}`;
}

/**
Expand Down
18 changes: 8 additions & 10 deletions src/templates/json/overrides/thepixel--bul-eds.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,27 +15,25 @@ import { JSONTemplate } from '../JSONTemplate.js';
export default class extends JSONTemplate {
/**
* @param {Variant} [variant]
* @param {Pick<Product, 'sku'|'urlKey'>} [pproduct]
* @returns {string}
*/
constructProductURL(variant) {
const {
product,
ctx: { config },
} = this;
constructProductURL(variant, pproduct) {
const product = pproduct || this.product;
const { ctx: { config } } = this;
const { host, matchedPatterns } = config;

const productPath = matchedPatterns[0]
.replace('{{urlkey}}', product.urlKey)
.replace('{{sku}}', encodeURIComponent(product.sku.toLowerCase()));

const productUrl = `${host}${productPath}`;

if (variant) {
const options = variant.selections.map((selection) => atob(selection)).join(',').replace(/configurable\//g, '').replace(/\//g, '-');
return `${productUrl}?pid=${variant.externalId}&o=${btoa(options)}`;
if (!variant) {
return productUrl;
}

return productUrl;
const options = variant.selections.map((selection) => atob(selection)).join(',').replace(/configurable\//g, '').replace(/\//g, '-');
return `${productUrl}?pid=${variant.externalId}&o=${btoa(options)}`;
}

// eslint-disable-next-line class-methods-use-this
Expand Down
9 changes: 8 additions & 1 deletion src/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,8 @@ declare global {
externalId?: string;
variants?: Variant[]; // variants exist on products in helix commerce but not on magento
specialToDate?: string;
rating?: Rating
rating?: Rating;
links?: Link[];

// not handled currently:
externalParentId?: string;
Expand Down Expand Up @@ -140,6 +141,12 @@ declare global {
worst?: number | string;
}

interface Link {
types: string[];
sku: string;
urlKey: string;
}

interface Image {
url: string;
label: string;
Expand Down

0 comments on commit 7980da2

Please sign in to comment.