Skip to content
This repository has been archived by the owner on Feb 23, 2024. It is now read-only.

Commit

Permalink
Fix corrupt Classic Template placeholders for specific products. (#7033)
Browse files Browse the repository at this point in the history
* If user has created a template for a specific product, find the closest matching template details

* Move Classic Template functions into Utils file and refactor function for specific template names

* Classic Template utils refactor and unit tests
  • Loading branch information
tjcafferkey authored Sep 6, 2022
1 parent 788e8a5 commit ed3abbe
Show file tree
Hide file tree
Showing 5 changed files with 129 additions and 26 deletions.
8 changes: 6 additions & 2 deletions assets/js/blocks/classic-template/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,14 @@
* External dependencies
*/
import { __ } from '@wordpress/i18n';

export const BLOCK_SLUG = 'woocommerce/legacy-template';

export const TEMPLATES: Record< string, Record< string, string > > = {
/**
* Internal dependencies
*/
import { TemplateDetails } from './types';

export const TEMPLATES: TemplateDetails = {
'single-product': {
title: __(
'WooCommerce Single Product Block',
Expand Down
50 changes: 26 additions & 24 deletions assets/js/blocks/classic-template/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
* External dependencies
*/
import {
Block,
BlockEditProps,
createBlock,
getBlockType,
Expand All @@ -26,6 +25,11 @@ import { useEffect } from '@wordpress/element';
import './editor.scss';
import './style.scss';
import { BLOCK_SLUG, TEMPLATES } from './constants';
import {
isClassicTemplateBlockRegisteredWithAnotherTitle,
hasTemplateSupportForClassicTemplateBlock,
getTemplateDetailsBySlug,
} from './utils';

type Attributes = {
template: string;
Expand All @@ -40,10 +44,12 @@ const Edit = ( {
const { replaceBlock } = useDispatch( 'core/block-editor' );

const blockProps = useBlockProps();
const templateTitle =
TEMPLATES[ attributes.template ]?.title ?? attributes.template;
const templatePlaceholder =
TEMPLATES[ attributes.template ]?.placeholder ?? 'fallback';
const templateDetails = getTemplateDetailsBySlug(
attributes.template,
TEMPLATES
);
const templateTitle = templateDetails?.title ?? attributes.template;
const templatePlaceholder = templateDetails?.placeholder ?? 'fallback';

useEffect(
() =>
Expand Down Expand Up @@ -118,8 +124,6 @@ const Edit = ( {
);
};

const templates = Object.keys( TEMPLATES );

const registerClassicTemplateBlock = ( {
template,
inserter,
Expand All @@ -136,12 +140,13 @@ const registerClassicTemplateBlock = ( {
* See https://github.com/woocommerce/woocommerce-gutenberg-products-block/issues/5861 for more context
*/
registerBlockType( BLOCK_SLUG, {
title: template
? TEMPLATES[ template ].title
: __(
'WooCommerce Classic Template',
'woo-gutenberg-products-block'
),
title:
template && TEMPLATES[ template ]
? TEMPLATES[ template ].title
: __(
'WooCommerce Classic Template',
'woo-gutenberg-products-block'
),
icon: (
<Icon
icon={ box }
Expand Down Expand Up @@ -202,15 +207,6 @@ const registerClassicTemplateBlock = ( {
} );
};

const isClassicTemplateBlockRegisteredWithAnotherTitle = (
// eslint-disable-next-line @typescript-eslint/no-explicit-any
block: Block< any > | undefined,
parsedTemplate: string
) => block?.title !== TEMPLATES[ parsedTemplate ].title;

const hasTemplateSupportForClassicTemplateBlock = ( parsedTemplate: string ) =>
templates.includes( parsedTemplate );

// @todo Refactor when there will be possible to show a block according on a template/post with a Gutenberg API. https://github.com/WordPress/gutenberg/pull/41718

let currentTemplateId: string | undefined;
Expand All @@ -235,7 +231,10 @@ if ( isExperimentalBuild() ) {

if (
block !== undefined &&
( ! hasTemplateSupportForClassicTemplateBlock( parsedTemplate ) ||
( ! hasTemplateSupportForClassicTemplateBlock(
parsedTemplate,
TEMPLATES
) ||
isClassicTemplateBlockRegisteredWithAnotherTitle(
block,
parsedTemplate
Expand All @@ -248,7 +247,10 @@ if ( isExperimentalBuild() ) {

if (
block === undefined &&
hasTemplateSupportForClassicTemplateBlock( parsedTemplate )
hasTemplateSupportForClassicTemplateBlock(
parsedTemplate,
TEMPLATES
)
) {
registerClassicTemplateBlock( {
template: parsedTemplate,
Expand Down
47 changes: 47 additions & 0 deletions assets/js/blocks/classic-template/test/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/**
* Internal dependencies
*/
import { getTemplateDetailsBySlug } from '../utils';

const TEMPLATES = {
'single-product': {
title: 'Single Product Title',
placeholder: 'Single Product Placeholder',
},
'archive-product': {
title: 'Product Archive Title',
placeholder: 'Product Archive Placeholder',
},
'archive-product': {
title: 'Product Archive Title',
placeholder: 'Product Archive Placeholder',
},
'taxonomy-product_cat': {
title: 'Product Taxonomy Title',
placeholder: 'Product Taxonomy Placeholder',
},
};

describe( 'getTemplateDetailsBySlug', function () {
it( 'should return single-product object when given an exact match', () => {
expect(
getTemplateDetailsBySlug( 'single-product', TEMPLATES )
).toBeTruthy();
expect(
getTemplateDetailsBySlug( 'single-product', TEMPLATES )
).toStrictEqual( TEMPLATES[ 'single-product' ] );
} );

it( 'should return single-product object when given a partial match', () => {
expect(
getTemplateDetailsBySlug( 'single-product-hoodie', TEMPLATES )
).toBeTruthy();
expect(
getTemplateDetailsBySlug( 'single-product-hoodie', TEMPLATES )
).toStrictEqual( TEMPLATES[ 'single-product' ] );
} );

it( 'should return null object when given an incorrect match', () => {
expect( getTemplateDetailsBySlug( 'void', TEMPLATES ) ).toBeNull();
} );
} );
1 change: 1 addition & 0 deletions assets/js/blocks/classic-template/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export type TemplateDetails = Record< string, Record< string, string > >;
49 changes: 49 additions & 0 deletions assets/js/blocks/classic-template/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/**
* External dependencies
*/
import { Block } from '@wordpress/blocks';

/**
* Internal dependencies
*/
import { TEMPLATES } from './constants';
import { TemplateDetails } from './types';

// Finds the most appropriate template details object for specific template keys such as single-product-hoodie.
export function getTemplateDetailsBySlug(
parsedTemplate: string,
templates: TemplateDetails
) {
const templateKeys = Object.keys( templates );
let templateDetails = null;

for ( let i = 0; templateKeys.length > i; i++ ) {
const keyToMatch = parsedTemplate.substr( 0, templateKeys[ i ].length );
const maybeTemplate = templates[ keyToMatch ];
if ( maybeTemplate ) {
templateDetails = maybeTemplate;
break;
}
}

return templateDetails;
}

export function isClassicTemplateBlockRegisteredWithAnotherTitle(
// eslint-disable-next-line @typescript-eslint/no-explicit-any
block: Block< any > | undefined,
parsedTemplate: string
) {
const templateDetails = getTemplateDetailsBySlug(
parsedTemplate,
TEMPLATES
);
return block?.title !== templateDetails?.title;
}

export function hasTemplateSupportForClassicTemplateBlock(
parsedTemplate: string,
templates: TemplateDetails
): boolean {
return getTemplateDetailsBySlug( parsedTemplate, templates ) ? true : false;
}

0 comments on commit ed3abbe

Please sign in to comment.