Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update/editor template validation #38770

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 12 additions & 3 deletions packages/block-editor/src/components/provider/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* WordPress dependencies
*/
import { useDispatch } from '@wordpress/data';
import { useEffect } from '@wordpress/element';
import { useEffect, useLayoutEffect } from '@wordpress/element';

/**
* Internal dependencies
Expand All @@ -15,13 +15,22 @@ import { BlockRefsProvider } from './block-refs-provider';
/** @typedef {import('@wordpress/data').WPDataRegistry} WPDataRegistry */

function BlockEditorProvider( props ) {
const { children, settings } = props;
const { children, settings, value: controlledBlocks } = props;

const { updateSettings, validateBlocksToTemplate } = useDispatch(
blockEditorStore
);

const { updateSettings } = useDispatch( blockEditorStore );
useEffect( () => {
updateSettings( settings );
}, [ settings ] );

useLayoutEffect( () => {
if ( controlledBlocks ) {
validateBlocksToTemplate( controlledBlocks );
}
}, [ settings ] );

// Syncs the entity provider with changes in the block-editor store.
useBlockSync( props );

Expand Down
4 changes: 2 additions & 2 deletions packages/block-editor/src/store/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,6 @@ const ensureDefaultBlock = () => ( { select, dispatch } ) => {
*/
export const resetBlocks = ( blocks ) => ( { dispatch } ) => {
dispatch( { type: 'RESET_BLOCKS', blocks } );
dispatch( validateBlocksToTemplate( blocks ) );
};

/**
Expand All @@ -72,13 +71,14 @@ export const validateBlocksToTemplate = ( blocks ) => ( {
} ) => {
const template = select.getTemplate();
const templateLock = select.getTemplateLock();
const getBlockListSettings = select.getBlockListSettings;

// Unlocked templates are considered always valid because they act
// as default values only.
const isBlocksValidToTemplate =
! template ||
templateLock !== 'all' ||
doBlocksMatchTemplate( blocks, template );
doBlocksMatchTemplate( blocks, template, getBlockListSettings );

// Update if validity has changed.
const isValidTemplate = select.isValidTemplate();
Expand Down
1 change: 1 addition & 0 deletions packages/blocks/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,7 @@ _Parameters_

- _blocks_ `Array`: Block list.
- _template_ `Array`: Block template.
- _getBlockListSettings_ `Function`: Gets block list settings.

_Returns_

Expand Down
21 changes: 17 additions & 4 deletions packages/blocks/src/api/templates.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,32 @@ import { getBlockType } from './registration';
/**
* Checks whether a list of blocks matches a template by comparing the block names.
*
* @param {Array} blocks Block list.
* @param {Array} template Block template.
* @param {Array} blocks Block list.
* @param {Array} template Block template.
* @param {Function} getBlockListSettings Gets block list settings.
*
* @return {boolean} Whether the list of blocks matches a templates.
*/
export function doBlocksMatchTemplate( blocks = [], template = [] ) {
export function doBlocksMatchTemplate(
blocks = [],
template = [],
getBlockListSettings = () => ( {} )
) {
return (
blocks.length === template.length &&
every( template, ( [ name, , innerBlocksTemplate ], index ) => {
const block = blocks[ index ];
const { clientId, innerBlocks } = block;
const { templateLock = null } =
getBlockListSettings( clientId ) ?? {};
return (
name === block.name &&
doBlocksMatchTemplate( block.innerBlocks, innerBlocksTemplate )
( templateLock === false ||
doBlocksMatchTemplate(
innerBlocks,
innerBlocksTemplate,
getBlockListSettings
) )
);
} )
);
Expand Down