Skip to content

Commit

Permalink
Move slug and title functions to shared utils file. Make sure the tit…
Browse files Browse the repository at this point in the history
…le is unique on conversion. (#47082)
  • Loading branch information
apeatling authored Jan 12, 2023
1 parent 7e52fbb commit 10f631b
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 56 deletions.
Original file line number Diff line number Diff line change
@@ -1,8 +1,3 @@
/**
* External dependencies
*/
import { kebabCase } from 'lodash';

/**
* WordPress dependencies
*/
Expand All @@ -20,7 +15,11 @@ import { plus } from '@wordpress/icons';
import { useHistory } from '../routes';
import { store as editSiteStore } from '../../store';
import CreateTemplatePartModal from '../create-template-part-modal';
import { useExistingTemplateParts } from './utils';
import {
useExistingTemplateParts,
getUniqueTemplatePartTitle,
getCleanTemplatePartSlug,
} from '../../utils/template-part-create';

export default function NewTemplatePart( {
postType,
Expand All @@ -42,39 +41,19 @@ export default function NewTemplatePart( {
return;
}

const uniqueTitle = () => {
const lowercaseTitle = title.toLowerCase();
const existingTitles = existingTemplateParts.map(
( templatePart ) => templatePart.title.rendered.toLowerCase()
);

if ( ! existingTitles.includes( lowercaseTitle ) ) {
return title;
}

let suffix = 2;
while (
existingTitles.includes( `${ lowercaseTitle } ${ suffix }` )
) {
suffix++;
}

return `${ title } ${ suffix }`;
};

try {
// Currently template parts only allow latin chars.
// Fallback slug will receive suffix by default.
const cleanSlug =
kebabCase( title ).replace( /[^\w-]+/g, '' ) ||
'wp-custom-part';
const cleanSlug = getCleanTemplatePartSlug( title );
const uniqueTitle = getUniqueTemplatePartTitle(
title,
existingTemplateParts
);

const templatePart = await saveEntityRecord(
'postType',
'wp_template_part',
{
slug: cleanSlug,
title: uniqueTitle(),
title: uniqueTitle,
content: '',
area,
},
Expand Down
14 changes: 0 additions & 14 deletions packages/edit-site/src/components/add-new-template/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,20 +52,6 @@ export const useExistingTemplates = () => {
);
};

export const useExistingTemplateParts = () => {
return useSelect(
( select ) =>
select( coreStore ).getEntityRecords(
'postType',
'wp_template_part',
{
per_page: -1,
}
),
[]
);
};

export const useDefaultTemplateTypes = () => {
return useSelect(
( select ) =>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,3 @@
/**
* External dependencies
*/
import { kebabCase } from 'lodash';

/**
* WordPress dependencies
*/
Expand All @@ -24,12 +19,18 @@ import { symbolFilled } from '@wordpress/icons';
*/
import CreateTemplatePartModal from '../create-template-part-modal';
import { store as editSiteStore } from '../../store';
import {
useExistingTemplateParts,
getUniqueTemplatePartTitle,
getCleanTemplatePartSlug,
} from '../../utils/template-part-create';

export default function ConvertToTemplatePart( { clientIds, blocks } ) {
const [ isModalOpen, setIsModalOpen ] = useState( false );
const { replaceBlocks } = useDispatch( blockEditorStore );
const { saveEntityRecord } = useDispatch( coreStore );
const { createSuccessNotice } = useDispatch( noticesStore );
const existingTemplateParts = useExistingTemplateParts();

const { canCreate } = useSelect( ( select ) => {
const { supportsTemplatePartsMode } =
Expand All @@ -44,17 +45,18 @@ export default function ConvertToTemplatePart( { clientIds, blocks } ) {
}

const onConvert = async ( { title, area } ) => {
// Currently template parts only allow latin chars.
// Fallback slug will receive suffix by default.
const cleanSlug =
kebabCase( title ).replace( /[^\w-]+/g, '' ) || 'wp-custom-part';
const cleanSlug = getCleanTemplatePartSlug( title );
const uniqueTitle = getUniqueTemplatePartTitle(
title,
existingTemplateParts
);

const templatePart = await saveEntityRecord(
'postType',
'wp_template_part',
{
slug: cleanSlug,
title,
title: uniqueTitle,
content: serialize( blocks ),
area,
}
Expand Down
62 changes: 62 additions & 0 deletions packages/edit-site/src/utils/template-part-create.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/**
* External dependencies
*/
import { kebabCase } from 'lodash';

/**
* WordPress dependencies
*/
import { useSelect } from '@wordpress/data';
import { store as coreStore } from '@wordpress/core-data';

export const useExistingTemplateParts = () => {
return useSelect(
( select ) =>
select( coreStore ).getEntityRecords(
'postType',
'wp_template_part',
{
per_page: -1,
}
),
[]
);
};

/**
* Return a unique template part title based on
* the given title and existing template parts.
*
* @param {string} title The original template part title.
* @param {Object} templateParts The array of template part entities.
* @return {string} A unique template part title.
*/
export const getUniqueTemplatePartTitle = ( title, templateParts ) => {
const lowercaseTitle = title.toLowerCase();
const existingTitles = templateParts.map( ( templatePart ) =>
templatePart.title.rendered.toLowerCase()
);

if ( ! existingTitles.includes( lowercaseTitle ) ) {
return title;
}

let suffix = 2;
while ( existingTitles.includes( `${ lowercaseTitle } ${ suffix }` ) ) {
suffix++;
}

return `${ title } ${ suffix }`;
};

/**
* Get a valid slug for a template part.
* Currently template parts only allow latin chars.
* The fallback slug will receive suffix by default.
*
* @param {string} title The template part title.
* @return {string} A valid template part slug.
*/
export const getCleanTemplatePartSlug = ( title ) => {
return kebabCase( title ).replace( /[^\w-]+/g, '' ) || 'wp-custom-part';
};

0 comments on commit 10f631b

Please sign in to comment.