From 215179e460ed25087cac65b3610517a5436a30d4 Mon Sep 17 00:00:00 2001 From: Bernie Reiter Date: Wed, 29 May 2024 12:32:42 +0200 Subject: [PATCH 01/17] block.json schema: Allow passing filename as variations argument --- schemas/json/block.json | 163 +++++++++++++++++++++------------------- 1 file changed, 85 insertions(+), 78 deletions(-) diff --git a/schemas/json/block.json b/schemas/json/block.json index 0c036a6e05ffe..8466b69c7e7ab 100644 --- a/schemas/json/block.json +++ b/schemas/json/block.json @@ -897,91 +897,98 @@ ] }, "variations": { - "type": "array", "description": "Block Variations is the API that allows a block to have similar versions of it, but all these versions share some common functionality.", - "items": { - "type": "object", - "required": [ "name", "title" ], - "additionalProperties": false, - "properties": { - "name": { - "type": "string", - "description": "The unique and machine-readable name." - }, - "title": { - "type": "string", - "description": "A human-readable variation title." - }, - "description": { - "type": "string", - "description": "A detailed variation description." - }, - "category": { - "description": "A category classification, used in search interfaces to arrange block types by category.", - "anyOf": [ - { - "type": "string" + "oneOf": [ + { + "type": "string" + }, + { + "type": "array", + "items": { + "type": "object", + "required": [ "name", "title" ], + "additionalProperties": false, + "properties": { + "name": { + "type": "string", + "description": "The unique and machine-readable name." }, - { - "enum": [ - "text", - "media", - "design", - "widgets", - "theme", - "embed" + "title": { + "type": "string", + "description": "A human-readable variation title." + }, + "description": { + "type": "string", + "description": "A detailed variation description." + }, + "category": { + "description": "A category classification, used in search interfaces to arrange block types by category.", + "anyOf": [ + { + "type": "string" + }, + { + "enum": [ + "text", + "media", + "design", + "widgets", + "theme", + "embed" + ] + } ] + }, + "icon": { + "description": "An icon helping to visualize the variation. It can have the same shape as the block type.", + "type": "string" + }, + "isDefault": { + "type": "boolean", + "default": false, + "description": "Indicates whether the current variation is the default one." + }, + "attributes": { + "type": "object", + "description": "Values that override block attributes." + }, + "innerBlocks": { + "type": "array", + "items": { + "type": "array" + }, + "description": "Initial configuration of nested blocks." + }, + "example": { + "type": "object", + "description": "Example provides structured data for the block preview. You can set to undefined to disable the preview shown for the block type." + }, + "scope": { + "type": "array", + "description": "The list of scopes where the variation is applicable.", + "items": { + "enum": [ "inserter", "block", "transform" ] + }, + "default": [ "inserter", "block" ] + }, + "keywords": { + "type": "array", + "description": "An array of terms (which can be translated) that help users discover the variation while searching.", + "items": { + "type": "string" + } + }, + "isActive": { + "type": "array", + "items": { + "type": "string" + }, + "description": "The list of attributes that should be compared. Each attributes will be matched and the variation will be active if all of them are matching." } - ] - }, - "icon": { - "description": "An icon helping to visualize the variation. It can have the same shape as the block type.", - "type": "string" - }, - "isDefault": { - "type": "boolean", - "default": false, - "description": "Indicates whether the current variation is the default one." - }, - "attributes": { - "type": "object", - "description": "Values that override block attributes." - }, - "innerBlocks": { - "type": "array", - "items": { - "type": "array" - }, - "description": "Initial configuration of nested blocks." - }, - "example": { - "type": "object", - "description": "Example provides structured data for the block preview. You can set to undefined to disable the preview shown for the block type." - }, - "scope": { - "type": "array", - "description": "The list of scopes where the variation is applicable.", - "items": { - "enum": [ "inserter", "block", "transform" ] - }, - "default": [ "inserter", "block" ] - }, - "keywords": { - "type": "array", - "description": "An array of terms (which can be translated) that help users discover the variation while searching.", - "items": { - "type": "string" } - }, - "isActive": { - "type": "array", - "items": { - "type": "string" - }, - "description": "The list of attributes that should be compared. Each attributes will be matched and the variation will be active if all of them are matching." } } - } + ] }, "render": { "type": "string", From ece51bf118adc62acd5e17b43f6191a2ac865179 Mon Sep 17 00:00:00 2001 From: Bernie Reiter Date: Tue, 18 Jun 2024 12:05:12 +0200 Subject: [PATCH 02/17] Add compat layer --- lib/compat/wordpress-6.7/blocks.php | 45 +++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 lib/compat/wordpress-6.7/blocks.php diff --git a/lib/compat/wordpress-6.7/blocks.php b/lib/compat/wordpress-6.7/blocks.php new file mode 100644 index 0000000000000..5cb14a9cea51b --- /dev/null +++ b/lib/compat/wordpress-6.7/blocks.php @@ -0,0 +1,45 @@ + Date: Tue, 18 Jun 2024 12:26:12 +0200 Subject: [PATCH 03/17] Add unit test --- .../block-json-variations-filename-test.php | 54 +++++++++++++++++++ phpunit/fixtures/variations.php | 10 ++++ 2 files changed, 64 insertions(+) create mode 100644 phpunit/blocks/block-json-variations-filename-test.php create mode 100644 phpunit/fixtures/variations.php diff --git a/phpunit/blocks/block-json-variations-filename-test.php b/phpunit/blocks/block-json-variations-filename-test.php new file mode 100644 index 0000000000000..2335487880eb2 --- /dev/null +++ b/phpunit/blocks/block-json-variations-filename-test.php @@ -0,0 +1,54 @@ +is_registered( 'my-plugin/notice' ) ) { + $registry->unregister( 'my-plugin/notice' ); + } + + parent::tear_down(); + } + + /** + * Tests registering a block with variations from a PHP file. + * + * @covers ::register_block_type_from_metadata + */ + public function test_register_block_type_from_metadata_with_variations_php_file() { + $filter_metadata_registration = static function ( $metadata ) { + $metadata['variations'] = 'variations.php'; + return $metadata; + }; + + add_filter( 'block_type_metadata', $filter_metadata_registration, 10, 2 ); + $result = register_block_type_from_metadata( GUTENBERG_DIR_TESTFIXTURES ); + remove_filter( 'block_type_metadata', $filter_metadata_registration ); + + $this->assertInstanceOf( 'WP_Block_Type', $result, 'The block was not registered' ); + + $this->assertIsCallable( $result->variation_callback, 'The variation callback hasn\'t been set' ); + $expected_variations = require GUTENBERG_DIR_TESTFIXTURES . '/variations.php'; + $this->assertSame( + $expected_variations, + call_user_func( $result->variation_callback ), + 'The variation callback hasn\'t been set correctly' + ); + $this->assertSame( $expected_variations, $result->variations, 'The block variations are incorrect' ); + } +} diff --git a/phpunit/fixtures/variations.php b/phpunit/fixtures/variations.php new file mode 100644 index 0000000000000..59a62c7244108 --- /dev/null +++ b/phpunit/fixtures/variations.php @@ -0,0 +1,10 @@ + 'warning', + 'title' => 'warning', + 'description' => 'Shows warning.', + 'keywords' => array( 'warning' ) + ) +); From 0a1c1a2b6a5b14ed7ecfe405b393226a467c18bd Mon Sep 17 00:00:00 2001 From: Bernie Reiter Date: Tue, 18 Jun 2024 12:26:31 +0200 Subject: [PATCH 04/17] Actually load compat layer --- lib/load.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/load.php b/lib/load.php index 201bfe1967d5b..d337567f24371 100644 --- a/lib/load.php +++ b/lib/load.php @@ -141,6 +141,9 @@ function gutenberg_is_experiment_enabled( $name ) { require __DIR__ . '/compat/wordpress-6.6/option.php'; require __DIR__ . '/compat/wordpress-6.6/post.php'; +// WordPress 6.7 compat. +require __DIR__ . '/compat/wordpress-6.7/blocks.php'; + // Experimental features. require __DIR__ . '/experimental/block-editor-settings-mobile.php'; require __DIR__ . '/experimental/blocks.php'; From 143051911de7e91f5bbc8614bb5921fdc02ba7ce Mon Sep 17 00:00:00 2001 From: Bernie Reiter Date: Tue, 18 Jun 2024 14:37:48 +0200 Subject: [PATCH 05/17] Coding Standards --- phpunit/fixtures/variations.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/phpunit/fixtures/variations.php b/phpunit/fixtures/variations.php index 59a62c7244108..bed66d9544176 100644 --- a/phpunit/fixtures/variations.php +++ b/phpunit/fixtures/variations.php @@ -5,6 +5,6 @@ 'name' => 'warning', 'title' => 'warning', 'description' => 'Shows warning.', - 'keywords' => array( 'warning' ) - ) + 'keywords' => array( 'warning' ), + ), ); From 07aa580246561f31478461515b78420b9b278ccf Mon Sep 17 00:00:00 2001 From: Bernie Reiter Date: Tue, 18 Jun 2024 16:26:37 +0200 Subject: [PATCH 06/17] Use 'file:' prefix --- phpunit/blocks/block-json-variations-filename-test.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpunit/blocks/block-json-variations-filename-test.php b/phpunit/blocks/block-json-variations-filename-test.php index 2335487880eb2..042d951945c8e 100644 --- a/phpunit/blocks/block-json-variations-filename-test.php +++ b/phpunit/blocks/block-json-variations-filename-test.php @@ -32,7 +32,7 @@ public function tear_down() { */ public function test_register_block_type_from_metadata_with_variations_php_file() { $filter_metadata_registration = static function ( $metadata ) { - $metadata['variations'] = 'variations.php'; + $metadata['variations'] = 'file:./variations.php'; return $metadata; }; From eefe6e30cd7197a656fc7b4a879aab459a4fb73d Mon Sep 17 00:00:00 2001 From: Bernie Reiter Date: Tue, 18 Jun 2024 16:30:23 +0200 Subject: [PATCH 07/17] Update docs --- docs/reference-guides/block-api/block-metadata.md | 10 +++++++++- docs/reference-guides/block-api/block-registration.md | 4 +++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/docs/reference-guides/block-api/block-metadata.md b/docs/reference-guides/block-api/block-metadata.md index 1b0925513b3a8..904a9b0e6d015 100644 --- a/docs/reference-guides/block-api/block-metadata.md +++ b/docs/reference-guides/block-api/block-metadata.md @@ -427,7 +427,7 @@ See the [Example documentation](/docs/reference-guides/block-api/block-registrat ### Variations -- Type: `object[]` +- Type: `object[]|string` - Optional - Localized: Yes (`title`, `description`, and `keywords` of each variation only) - Property: `variations` @@ -454,6 +454,14 @@ Block Variations is the API that allows a block to have similar versions of it, _Note: In JavaScript you can provide a function for the `isActive` property, and a React element for the `icon`. In the `block.json` file both only support strings_ +_Note: Starting with version 6.7, it is possible to specify a PHP file that generates the list of block variations on the server side:_ + +```json +{ + "variations": "file:./variations.php" +} +``` + See [the variations documentation](/docs/reference-guides/block-api/block-variations.md) for more details. ### Block Hooks diff --git a/docs/reference-guides/block-api/block-registration.md b/docs/reference-guides/block-api/block-registration.md index 92be19ee48c9f..1720b75dbc68b 100644 --- a/docs/reference-guides/block-api/block-registration.md +++ b/docs/reference-guides/block-api/block-registration.md @@ -233,11 +233,13 @@ example: { #### variations (optional) -- **Type:** `Object[]` +- **Type:** `Object[]|string` - **Since**: `WordPress 5.9.0` Similarly to how the block's styles can be declared, a block type can define block variations that the user can pick from. The difference is that, rather than changing only the visual appearance, this field provides a way to apply initial custom attributes and inner blocks at the time when a block is inserted. See the [Block Variations API](/docs/reference-guides/block-api/block-variations.md) for more details. +_Note:_ Starting with WordPress 6.7, it is possible to specify a PHP file that generates the list of block variations on the server side. + #### supports (optional) - **_Type:_** `Object` From 2498f5d18e46f4710f47783a42ef2e1b9f00178b Mon Sep 17 00:00:00 2001 From: Bernie Reiter Date: Tue, 18 Jun 2024 17:26:36 +0200 Subject: [PATCH 08/17] Remove assertions that would break for WP < 6.5 --- phpunit/blocks/block-json-variations-filename-test.php | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/phpunit/blocks/block-json-variations-filename-test.php b/phpunit/blocks/block-json-variations-filename-test.php index 042d951945c8e..3cbbb05aa59b0 100644 --- a/phpunit/blocks/block-json-variations-filename-test.php +++ b/phpunit/blocks/block-json-variations-filename-test.php @@ -42,13 +42,7 @@ public function test_register_block_type_from_metadata_with_variations_php_file( $this->assertInstanceOf( 'WP_Block_Type', $result, 'The block was not registered' ); - $this->assertIsCallable( $result->variation_callback, 'The variation callback hasn\'t been set' ); $expected_variations = require GUTENBERG_DIR_TESTFIXTURES . '/variations.php'; - $this->assertSame( - $expected_variations, - call_user_func( $result->variation_callback ), - 'The variation callback hasn\'t been set correctly' - ); - $this->assertSame( $expected_variations, $result->variations, 'The block variations are incorrect' ); + $this->assertSame( $expected_variations, $result->variations, "Block variations haven't been set correctly." ); } } From c2cd0234c210263bd53f253e705df1e339ca906c Mon Sep 17 00:00:00 2001 From: Bernie Reiter Date: Tue, 18 Jun 2024 17:48:52 +0200 Subject: [PATCH 09/17] Add backport changelog --- backport-changelog/6.7/6668.md | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 backport-changelog/6.7/6668.md diff --git a/backport-changelog/6.7/6668.md b/backport-changelog/6.7/6668.md new file mode 100644 index 0000000000000..7653dd8d8294e --- /dev/null +++ b/backport-changelog/6.7/6668.md @@ -0,0 +1,3 @@ +https://github.com/WordPress/wordpress-develop/pull/6668 + +* https://github.com/WordPress/gutenberg/pull/62092 From bd378a65e7265990aa8b1d05ff36bf89ad91aa72 Mon Sep 17 00:00:00 2001 From: Tom Cafferkey Date: Tue, 25 Jun 2024 10:47:00 +0100 Subject: [PATCH 10/17] Check that the variation is an array before merging now that they can be filePaths (strings) as well --- packages/blocks/src/store/process-block-type.js | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/packages/blocks/src/store/process-block-type.js b/packages/blocks/src/store/process-block-type.js index 154f74c6ab729..9c171f2c7e0f4 100644 --- a/packages/blocks/src/store/process-block-type.js +++ b/packages/blocks/src/store/process-block-type.js @@ -93,9 +93,14 @@ export const processBlockType = save: () => null, ...bootstrappedBlockType, ...blockSettings, + // blockType.variations can be defined as a filePath. variations: mergeBlockVariations( - bootstrappedBlockType?.variations, - blockSettings?.variations + Array.isArray( bootstrappedBlockType?.variations ) + ? bootstrappedBlockType.variations + : [], + Array.isArray( blockSettings?.variations ) + ? blockSettings.variations + : [] ), }; From 6f45ac54fd79e51dacb49538944db9e7cd44662c Mon Sep 17 00:00:00 2001 From: Bernie Reiter Date: Wed, 3 Jul 2024 11:26:44 +0200 Subject: [PATCH 11/17] Remove note from client-side block registration docs --- docs/reference-guides/block-api/block-registration.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/docs/reference-guides/block-api/block-registration.md b/docs/reference-guides/block-api/block-registration.md index 1720b75dbc68b..92be19ee48c9f 100644 --- a/docs/reference-guides/block-api/block-registration.md +++ b/docs/reference-guides/block-api/block-registration.md @@ -233,13 +233,11 @@ example: { #### variations (optional) -- **Type:** `Object[]|string` +- **Type:** `Object[]` - **Since**: `WordPress 5.9.0` Similarly to how the block's styles can be declared, a block type can define block variations that the user can pick from. The difference is that, rather than changing only the visual appearance, this field provides a way to apply initial custom attributes and inner blocks at the time when a block is inserted. See the [Block Variations API](/docs/reference-guides/block-api/block-variations.md) for more details. -_Note:_ Starting with WordPress 6.7, it is possible to specify a PHP file that generates the list of block variations on the server side. - #### supports (optional) - **_Type:_** `Object` From 8be51898e856ff5e155c04e728b6ef4d2adc283b Mon Sep 17 00:00:00 2001 From: Bernie Reiter Date: Wed, 3 Jul 2024 11:47:49 +0200 Subject: [PATCH 12/17] Document how to shape the variations PHP file --- .../block-api/block-metadata.md | 37 ++++++++++++++++--- 1 file changed, 32 insertions(+), 5 deletions(-) diff --git a/docs/reference-guides/block-api/block-metadata.md b/docs/reference-guides/block-api/block-metadata.md index 904a9b0e6d015..587c36f808283 100644 --- a/docs/reference-guides/block-api/block-metadata.md +++ b/docs/reference-guides/block-api/block-metadata.md @@ -427,7 +427,7 @@ See the [Example documentation](/docs/reference-guides/block-api/block-registrat ### Variations -- Type: `object[]|string` +- Type: `object[]|WPDefinedPath` ([learn more](#wpdefinedpath)) - Optional - Localized: Yes (`title`, `description`, and `keywords` of each variation only) - Property: `variations` @@ -454,12 +454,39 @@ Block Variations is the API that allows a block to have similar versions of it, _Note: In JavaScript you can provide a function for the `isActive` property, and a React element for the `icon`. In the `block.json` file both only support strings_ -_Note: Starting with version 6.7, it is possible to specify a PHP file that generates the list of block variations on the server side:_ +Starting with version 6.7, it is possible to specify a PHP file in `block.json` that generates the list of block variations on the server side: ```json -{ - "variations": "file:./variations.php" -} +{ "variations": "file:./variations.php" } +``` + +That PHP file is expected to `return` an array that contains the block variations. For example: + +```php + true, + 'name' => 'wordpress', + 'title' => 'WordPress', + 'icon' => 'wordpress', + 'attributes' => array( + 'service' => 'wordpress', + ), + 'isActive' => array( 'service' ) + ), + array( + 'name' => 'gravatar', + 'title' => 'Gravatar', + 'icon' => 'commentAuthorAvatar', + 'attributes' => array( + 'service' => 'gravatar', + ), + 'isActive' => array( 'service' ) + ), +); + ``` See [the variations documentation](/docs/reference-guides/block-api/block-variations.md) for more details. From fe484e00574b3d82d589bcacc09eac5362141380 Mon Sep 17 00:00:00 2001 From: Bernie Reiter Date: Wed, 3 Jul 2024 11:51:49 +0200 Subject: [PATCH 13/17] Change example to use __() --- docs/reference-guides/block-api/block-metadata.md | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/docs/reference-guides/block-api/block-metadata.md b/docs/reference-guides/block-api/block-metadata.md index 587c36f808283..b3070438b50a1 100644 --- a/docs/reference-guides/block-api/block-metadata.md +++ b/docs/reference-guides/block-api/block-metadata.md @@ -477,13 +477,17 @@ return array( 'isActive' => array( 'service' ) ), array( - 'name' => 'gravatar', - 'title' => 'Gravatar', - 'icon' => 'commentAuthorAvatar', + 'name' => 'mail', + 'title' => __( 'Mail' ), + 'keywords' => array( + __( 'email' ), + __( 'e-mail' ) + ), + 'icon' => 'mail', 'attributes' => array( - 'service' => 'gravatar', + 'service' => 'mail', ), - 'isActive' => array( 'service' ) + 'isActive' => array( 'mail' ) ), ); From fe5cca24282bbb63210e4b4c437b825749aed2a6 Mon Sep 17 00:00:00 2001 From: Bernie Reiter Date: Wed, 3 Jul 2024 11:54:03 +0200 Subject: [PATCH 14/17] Add note about l10n --- docs/reference-guides/block-api/block-metadata.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/reference-guides/block-api/block-metadata.md b/docs/reference-guides/block-api/block-metadata.md index b3070438b50a1..a747ab5f76aa0 100644 --- a/docs/reference-guides/block-api/block-metadata.md +++ b/docs/reference-guides/block-api/block-metadata.md @@ -460,7 +460,9 @@ Starting with version 6.7, it is possible to specify a PHP file in `block.json` { "variations": "file:./variations.php" } ``` -That PHP file is expected to `return` an array that contains the block variations. For example: +That PHP file is expected to `return` an array that contains the block variations. Strings found in the variations returned from the PHP file will not be localized automatically; instead, use the `__()` function as usual. + +For example: ```php Date: Wed, 3 Jul 2024 11:55:56 +0200 Subject: [PATCH 15/17] Add one more inline comment --- docs/reference-guides/block-api/block-metadata.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/reference-guides/block-api/block-metadata.md b/docs/reference-guides/block-api/block-metadata.md index a747ab5f76aa0..8dea562a45757 100644 --- a/docs/reference-guides/block-api/block-metadata.md +++ b/docs/reference-guides/block-api/block-metadata.md @@ -466,6 +466,7 @@ For example: ```php Date: Wed, 3 Jul 2024 12:58:52 +0200 Subject: [PATCH 16/17] Use `$settings['variations']` instead of `$metadata['variations']` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Greg Ziółkowski --- lib/compat/wordpress-6.7/blocks.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/compat/wordpress-6.7/blocks.php b/lib/compat/wordpress-6.7/blocks.php index 5cb14a9cea51b..18d21621be719 100644 --- a/lib/compat/wordpress-6.7/blocks.php +++ b/lib/compat/wordpress-6.7/blocks.php @@ -19,7 +19,7 @@ function gutenberg_filter_block_type_metadata_settings_allow_variations_php_file $variations_path = wp_normalize_path( realpath( dirname( $metadata['file'] ) . '/' . - remove_block_asset_path_prefix( $metadata['variations'] ) + remove_block_asset_path_prefix( $settings['variations'] ) ) ); if ( $variations_path ) { From be8a9c2ba3533b080f3bf14cb0834616332d95d3 Mon Sep 17 00:00:00 2001 From: Bernie Reiter Date: Tue, 9 Jul 2024 13:32:25 +0200 Subject: [PATCH 17/17] Add descriptions for both possible variations field types --- schemas/json/block.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/schemas/json/block.json b/schemas/json/block.json index 8466b69c7e7ab..6a27447f7b496 100644 --- a/schemas/json/block.json +++ b/schemas/json/block.json @@ -900,10 +900,12 @@ "description": "Block Variations is the API that allows a block to have similar versions of it, but all these versions share some common functionality.", "oneOf": [ { - "type": "string" + "type": "string", + "description": "The path to a PHP file that returns an array of block variations." }, { "type": "array", + "description": "An array of block variations.", "items": { "type": "object", "required": [ "name", "title" ],