From b71c06cfbef272fdee0f3c652aa44e39197325c7 Mon Sep 17 00:00:00 2001 From: Dave Smith Date: Thu, 8 Sep 2022 15:28:55 +0100 Subject: [PATCH 1/3] Adds metadata supports --- lib/compat/wordpress-6.1/blocks.php | 25 ++++++++ packages/block-editor/src/hooks/index.js | 2 + .../block-editor/src/hooks/metadata-name.js | 48 ++++++++++++++ packages/block-editor/src/hooks/metadata.js | 64 +++++++++++++++++++ 4 files changed, 139 insertions(+) create mode 100644 packages/block-editor/src/hooks/metadata-name.js create mode 100644 packages/block-editor/src/hooks/metadata.js diff --git a/lib/compat/wordpress-6.1/blocks.php b/lib/compat/wordpress-6.1/blocks.php index 82956d1bf8dd49..a33515632099b3 100644 --- a/lib/compat/wordpress-6.1/blocks.php +++ b/lib/compat/wordpress-6.1/blocks.php @@ -392,3 +392,28 @@ function gutenberg_block_type_metadata_render_template( $settings, $metadata ) { return $settings; } add_filter( 'block_type_metadata_settings', 'gutenberg_block_type_metadata_render_template', 10, 2 ); + +/** + * Registers the metadata block attribute for block types. + * + * Once 6.1 is the minimum supported WordPress version for the Gutenberg + * plugin, this shim can be removed + * + * @param array $args Array of arguments for registering a block type. + * @return array $args + */ +function gutenberg_register_metadata_attribute( $args ) { + // Setup attributes if needed. + if ( ! isset( $args['attributes'] ) || ! is_array( $args['attributes'] ) ) { + $args['attributes'] = array(); + } + + if ( ! array_key_exists( 'metadata', $args['attributes'] ) ) { + $args['attributes']['metadata'] = array( + 'type' => 'object', + ); + } + + return $args; +} +add_filter( 'register_block_type_args', 'gutenberg_register_metadata_attribute' ); diff --git a/packages/block-editor/src/hooks/index.js b/packages/block-editor/src/hooks/index.js index 5a07d864beb620..a47fcc72626aa3 100644 --- a/packages/block-editor/src/hooks/index.js +++ b/packages/block-editor/src/hooks/index.js @@ -16,6 +16,8 @@ import './font-size'; import './border'; import './layout'; import './content-lock-ui'; +import './metadata'; +import './metadata-name'; export { useCustomSides } from './dimensions'; export { getBorderClassesAndStyles, useBorderProps } from './use-border-props'; diff --git a/packages/block-editor/src/hooks/metadata-name.js b/packages/block-editor/src/hooks/metadata-name.js new file mode 100644 index 00000000000000..a32a05b53775b7 --- /dev/null +++ b/packages/block-editor/src/hooks/metadata-name.js @@ -0,0 +1,48 @@ +/** + * WordPress dependencies + */ +import { addFilter } from '@wordpress/hooks'; +/** + * Internal dependencies + */ +import { hasBlockMetadataSupport } from './metadata'; + +/** + * Filters registered block settings, adding an `__experimentalLabel` callback if one does not already exist. + * + * @param {Object} settings Original block settings. + * + * @return {Object} Filtered block settings. + */ +export function addLabelCallback( settings ) { + // If blocks provide their own label callback, do not override it. + if ( settings.__experimentalLabel ) { + return settings; + } + + const supportsBlockNaming = hasBlockMetadataSupport( + settings, + 'name', + false + ); + + // Check whether block metadata is supported before using it. + if ( supportsBlockNaming ) { + settings.__experimentalLabel = ( attributes, { context } ) => { + const { metadata } = attributes; + + // In the list view, use the block's name sattribute as the label. + if ( context === 'list-view' && metadata?.name ) { + return metadata.name; + } + }; + } + + return settings; +} + +addFilter( + 'blocks.registerBlockType', + 'core/metadata/addLabelCallback', + addLabelCallback +); diff --git a/packages/block-editor/src/hooks/metadata.js b/packages/block-editor/src/hooks/metadata.js new file mode 100644 index 00000000000000..5ed4870d56e4f0 --- /dev/null +++ b/packages/block-editor/src/hooks/metadata.js @@ -0,0 +1,64 @@ +/** + * WordPress dependencies + */ +import { addFilter } from '@wordpress/hooks'; +import { getBlockSupport } from '@wordpress/blocks'; + +const META_ATTRIBUTE_NAME = 'metadata'; + +export function hasBlockMetadataSupport( blockType, feature = '' ) { + const support = getBlockSupport( blockType, '__experimentalMetadata' ); + return !! ( true === support || support?.[ feature ] ); +} + +/** + * Filters registered block settings, extending attributes to include `metadata`. + * + * see: https://github.com/WordPress/gutenberg/pull/40393/files#r864632012 + * + * @param {Object} blockTypeSettings Original block settings. + * @return {Object} Filtered block settings. + */ +export function addMetaAttribute( blockTypeSettings ) { + // Allow blocks to specify their own attribute definition with default values if needed. + if ( blockTypeSettings?.attributes?.[ META_ATTRIBUTE_NAME ]?.type ) { + return blockTypeSettings; + } + + const supportsBlockNaming = hasBlockMetadataSupport( + blockTypeSettings, + 'name', + false + ); + + if ( supportsBlockNaming ) { + blockTypeSettings.attributes = { + ...blockTypeSettings.attributes, + [ META_ATTRIBUTE_NAME ]: { + type: 'object', + }, + }; + } + + return blockTypeSettings; +} + +export function addSaveProps( extraProps, blockType, attributes ) { + if ( hasBlockMetadataSupport( blockType ) ) { + extraProps[ META_ATTRIBUTE_NAME ] = attributes[ META_ATTRIBUTE_NAME ]; + } + + return extraProps; +} + +addFilter( + 'blocks.registerBlockType', + 'core/metadata/addMetaAttribute', + addMetaAttribute +); + +addFilter( + 'blocks.getSaveContent.extraProps', + 'core/metadata/save-props', + addSaveProps +); From 787974803b40a66fc3e415d37ca73ca946882eb8 Mon Sep 17 00:00:00 2001 From: Dave Smith Date: Mon, 12 Sep 2022 08:59:32 +0100 Subject: [PATCH 2/3] Correct spelling Co-authored-by: Ben Dwyer --- packages/block-editor/src/hooks/metadata-name.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/block-editor/src/hooks/metadata-name.js b/packages/block-editor/src/hooks/metadata-name.js index a32a05b53775b7..809be19bb6e6f3 100644 --- a/packages/block-editor/src/hooks/metadata-name.js +++ b/packages/block-editor/src/hooks/metadata-name.js @@ -31,7 +31,7 @@ export function addLabelCallback( settings ) { settings.__experimentalLabel = ( attributes, { context } ) => { const { metadata } = attributes; - // In the list view, use the block's name sattribute as the label. + // In the list view, use the block's name attribute as the label. if ( context === 'list-view' && metadata?.name ) { return metadata.name; } From fedab3dc4250041f60a5068e683c5c617ac43786 Mon Sep 17 00:00:00 2001 From: Dave Smith Date: Mon, 12 Sep 2022 09:03:15 +0100 Subject: [PATCH 3/3] Add explanatory comment --- packages/block-editor/src/hooks/metadata-name.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/block-editor/src/hooks/metadata-name.js b/packages/block-editor/src/hooks/metadata-name.js index 809be19bb6e6f3..6eecb0ce3667c4 100644 --- a/packages/block-editor/src/hooks/metadata-name.js +++ b/packages/block-editor/src/hooks/metadata-name.js @@ -23,7 +23,7 @@ export function addLabelCallback( settings ) { const supportsBlockNaming = hasBlockMetadataSupport( settings, 'name', - false + false // default value ); // Check whether block metadata is supported before using it.