Skip to content

Commit

Permalink
Expose Template part block variations to the Inserter (#30032)
Browse files Browse the repository at this point in the history
* Expose Template part block variations to the Inserter

* remove explicit check for `area` block attribute
  • Loading branch information
ntsekouras authored Mar 22, 2021
1 parent e10eae2 commit 1c2c0ae
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 24 deletions.
3 changes: 3 additions & 0 deletions packages/block-library/src/template-part/block.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@
},
"tagName": {
"type": "string"
},
"area": {
"type": "string"
}
},
"supports": {
Expand Down
4 changes: 3 additions & 1 deletion packages/block-library/src/template-part/edit/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,11 @@ import { TemplatePartAdvancedControls } from './advanced-controls';
import { getTagBasedOnArea } from './get-tag-based-on-area';

export default function TemplatePartEdit( {
attributes: { slug, theme, tagName, layout = {} },
attributes,
setAttributes,
clientId,
} ) {
const { slug, theme, tagName, layout = {} } = attributes;
const templatePartId = theme && slug ? theme + '//' + slug : null;

const [ hasAlreadyRendered, RecursionProvider ] = useNoRecursiveRenders(
Expand Down Expand Up @@ -116,6 +117,7 @@ export default function TemplatePartEdit( {
<TagName { ...blockProps }>
{ isPlaceholder && (
<TemplatePartPlaceholder
area={ attributes.area }
setAttributes={ setAttributes }
innerBlocks={ innerBlocks }
/>
Expand Down
22 changes: 16 additions & 6 deletions packages/block-library/src/template-part/edit/placeholder/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,26 +15,36 @@ import { store as coreStore } from '@wordpress/core-data';
import TemplatePartSelection from '../selection';

export default function TemplatePartPlaceholder( {
area,
setAttributes,
innerBlocks,
} ) {
const { saveEntityRecord } = useDispatch( coreStore );
const onCreate = useCallback( async () => {
const title = __( 'Untitled Template Part' );
// If we have `area` set from block attributes, means an exposed
// block variation was inserted. So add this prop to the template
// part entity on creation. Afterwards remove `area` value from
// block attributes.
const record = {
title,
slug: 'template-part',
content: serialize( innerBlocks ),
// `area` is filterable on the server and defaults to `UNCATEGORIZED`
// if provided value is not allowed.
area,
};
const templatePart = await saveEntityRecord(
'postType',
'wp_template_part',
{
title,
slug: 'template-part',
content: serialize( innerBlocks ),
}
record
);
setAttributes( {
slug: templatePart.slug,
theme: templatePart.theme,
area: undefined,
} );
}, [ setAttributes ] );
}, [ setAttributes, area ] );

return (
<Placeholder
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ function TemplatePartItem( {
const { createSuccessNotice } = useDispatch( noticesStore );

const onClick = useCallback( () => {
setAttributes( { slug, theme } );
setAttributes( { slug, theme, area: undefined } );
createSuccessNotice(
sprintf(
/* translators: %s: template part title. */
Expand Down
42 changes: 26 additions & 16 deletions packages/block-library/src/template-part/variations.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,6 @@ import { store as coreDataStore } from '@wordpress/core-data';
import { select } from '@wordpress/data';
import { __ } from '@wordpress/i18n';

const createIsActiveBasedOnArea = ( area ) => ( { theme, slug } ) => {
if ( ! slug ) {
return false;
}

const entity = select( coreDataStore ).getEntityRecord(
'postType',
'wp_template_part',
`${ theme }//${ slug }`
);

return entity?.area === area;
};

const variations = [
{
name: 'header',
Expand All @@ -28,7 +14,7 @@ const variations = [
"The header template defines a page area that typically contains a title, logo, and main navigation. Since it's a global element it can be present across all pages and posts."
),
icon: header,
isActive: createIsActiveBasedOnArea( 'header' ),
attributes: { area: 'header' },
scope: [ 'inserter' ],
},
{
Expand All @@ -38,9 +24,33 @@ const variations = [
"The footer template defines a page area that typically contains site credits, social links, or any other combination of blocks. Since it's a global element it can be present across all pages and posts."
),
icon: footer,
isActive: createIsActiveBasedOnArea( 'footer' ),
attributes: { area: 'footer' },
scope: [ 'inserter' ],
},
];

/**
* Add `isActive` function to all `Template Part` variations, if not defined.
* `isActive` function is used to find a variation match from a created
* Block by providing its attributes.
*/
variations.forEach( ( variation ) => {
if ( variation.isActive ) return;
variation.isActive = ( blockAttributes, variationAttributes ) => {
const { area, theme, slug } = blockAttributes;
// We first check the `area` block attribute which is set during insertion.
// This property is removed on the creation of a template part.
if ( area ) return area === variationAttributes.area;
// Find a matching variation from the created template part
// by checking the entity's `area` property.
if ( ! slug ) return false;
const entity = select( coreDataStore ).getEntityRecord(
'postType',
'wp_template_part',
`${ theme }//${ slug }`
);
return entity?.area === variationAttributes.area;
};
} );

export default variations;

0 comments on commit 1c2c0ae

Please sign in to comment.