Skip to content

Commit

Permalink
General: Add block_hooks field to block type registration, REST API.
Browse files Browse the repository at this point in the history
In order to implement Block Hooks, we need to add a new `block_hooks` field to the `WP_Block_Type` class, as well as to block registration related functions, the block types REST API controller, etc.

Props gziolo.
Fixes #59346. See #59313.

git-svn-id: https://develop.svn.wordpress.org/trunk@56587 602fd350-edb4-49c9-b593-d223f7449a82
  • Loading branch information
ockham committed Sep 14, 2023
1 parent e005108 commit 7b90f22
Show file tree
Hide file tree
Showing 8 changed files with 86 additions and 1 deletion.
2 changes: 2 additions & 0 deletions src/wp-admin/includes/post.php
Original file line number Diff line number Diff line change
Expand Up @@ -2207,6 +2207,7 @@ function taxonomy_meta_box_sanitize_cb_input( $taxonomy, $terms ) {
*
* @since 5.0.0
* @since 6.3.0 Added `selectors` field.
* @since 6.4.0 Added `block_hooks` field.
*
* @return array An associative array of registered block data.
*/
Expand All @@ -2221,6 +2222,7 @@ function get_block_editor_server_block_settings() {
'attributes' => 'attributes',
'provides_context' => 'providesContext',
'uses_context' => 'usesContext',
'block_hooks' => 'blockHooks',
'selectors' => 'selectors',
'supports' => 'supports',
'category' => 'category',
Expand Down
34 changes: 34 additions & 0 deletions src/wp-includes/blocks.php
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,7 @@ function get_block_metadata_i18n_schema() {
* @since 5.9.0 Added support for `variations` and `viewScript` fields.
* @since 6.1.0 Added support for `render` field.
* @since 6.3.0 Added `selectors` field.
* @since 6.4.0 Added support for `blockHooks` field.
*
* @param string $file_or_folder Path to the JSON file with metadata definition for
* the block or path to the folder where the `block.json` file is located.
Expand Down Expand Up @@ -513,6 +514,39 @@ function register_block_type_from_metadata( $file_or_folder, $args = array() ) {
}
}

if ( ! empty( $metadata['blockHooks'] ) ) {
/**
* Map camelCased position string (from block.json) to snake_cased block type position.
*
* @var array
*/
$position_mappings = array(
'before' => 'before',
'after' => 'after',
'firstChild' => 'first_child',
'lastChild' => 'last_child',
);

$settings['block_hooks'] = array();
foreach ( $metadata['blockHooks'] as $anchor_block_name => $position ) {
// Avoid infinite recursion (hooking to itself).
if ( $metadata['name'] === $anchor_block_name ) {
_doing_it_wrong(
__METHOD__,
__( 'Cannot hook block to itself.', 'gutenberg' ),

This comment has been minimized.

Copy link
@Soean

Soean Sep 14, 2023

Member

We should remove the 'gutenberg' text domain.

'6.4.0'
);
continue;
}

if ( ! isset( $position_mappings[ $position ] ) ) {
continue;
}

$settings['block_hooks'][ $anchor_block_name ] = $position_mappings[ $position ];
}
}

if ( ! empty( $metadata['render'] ) ) {
$template_path = wp_normalize_path(
realpath(
Expand Down
14 changes: 14 additions & 0 deletions src/wp-includes/class-wp-block-type.php
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,18 @@ class WP_Block_Type {
*/
public $provides_context = null;

/**
* Block hooks for this block type.
*
* A block hook is specified by a block type and a relative position.
* The hooked block will be automatically inserted in the given position
* next to the "anchor" block whenever the latter is encountered.
*
* @since 6.4.0
* @var array[]
*/
public $block_hooks = array();

/**
* Block type editor only script handles.
*
Expand Down Expand Up @@ -254,6 +266,7 @@ class WP_Block_Type {
* `editor_style_handles`, and `style_handles` properties.
* Deprecated the `editor_script`, `script`, `view_script`, `editor_style`, and `style` properties.
* @since 6.3.0 Added the `selectors` property.
* @since 6.4.0 Added the `block_hooks` property.
*
* @see register_block_type()
*
Expand Down Expand Up @@ -284,6 +297,7 @@ class WP_Block_Type {
* @type array|null $attributes Block type attributes property schemas.
* @type string[] $uses_context Context values inherited by blocks of this type.
* @type string[]|null $provides_context Context provided by blocks of this type.
* @type array[] $block_hooks Block hooks.
* @type string[] $editor_script_handles Block type editor only script handles.
* @type string[] $script_handles Block type front end and editor script handles.
* @type string[] $view_script_handles Block type front end only script handles.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,7 @@ public function prepare_item_for_response( $item, $request ) {
'editor_style_handles',
'style_handles',
'variations',
'block_hooks',
),
$deprecated_fields
);
Expand Down Expand Up @@ -706,6 +707,19 @@ public function get_item_schema() {
),
'keywords' => $keywords_definition,
'example' => $example_definition,
'block_hooks' => array(
'description' => __( 'This block is automatically inserted near any occurence of the block types used as keys of this map, into a relative position given by the corresponding value.' ),
'type' => 'object',
'patternProperties' => array(
'^[a-zA-Z0-9-]+/[a-zA-Z0-9-]+$' => array(
'type' => 'string',
'enum' => array( 'before', 'after', 'first_child', 'last_child' ),
),
),
'default' => array(),
'context' => array( 'embed', 'view', 'edit' ),
'readonly' => true,
),
),
);

Expand Down
3 changes: 3 additions & 0 deletions tests/phpunit/data/blocks/notice/block.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@
"selectors": {
"root": ".wp-block-notice"
},
"blockHooks": {
"core/post-content": "before"
},
"supports": {
"align": true,
"lightBlockWrapper": true
Expand Down
2 changes: 2 additions & 0 deletions tests/phpunit/tests/admin/includesPost.php
Original file line number Diff line number Diff line change
Expand Up @@ -918,6 +918,7 @@ public function test_get_block_editor_server_block_settings() {
'render_callback' => 'foo',
'ancestor' => array( 'core/test-ancestor' ),
'selectors' => array( 'root' => '.wp-block-test' ),
'block_hooks' => array( 'core/post-content' => 'before' ),
);

register_block_type( $name, $settings );
Expand All @@ -937,6 +938,7 @@ public function test_get_block_editor_server_block_settings() {
'lock' => array( 'type' => 'object' ),
),
'usesContext' => array(),
'blockHooks' => array( 'core/post-content' => 'before' ),
'selectors' => array( 'root' => '.wp-block-test' ),
'category' => 'common',
'styles' => array(),
Expand Down
6 changes: 6 additions & 0 deletions tests/phpunit/tests/blocks/register.php
Original file line number Diff line number Diff line change
Expand Up @@ -644,6 +644,12 @@ public function test_block_registers_with_metadata_fixture() {
$result->selectors,
'Block type should contain selectors from metadata.'
);
// @ticket 59346
$this->assertSame(
array( 'core/post-content' => 'before' ),
$result->block_hooks,
'Block type should contain block hooks from metadata.'
);
$this->assertSame(
array(
'align' => true,
Expand Down
12 changes: 11 additions & 1 deletion tests/phpunit/tests/rest-api/rest-block-type-controller.php
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,7 @@ public function test_get_block_invalid_name() {
/**
* @ticket 47620
* @ticket 57585
* @ticket 59346
*/
public function test_get_item_invalid() {
$block_type = 'fake/invalid';
Expand All @@ -205,6 +206,7 @@ public function test_get_item_invalid() {
'attributes' => 'invalid_attributes',
'provides_context' => 'invalid_provides_context',
'uses_context' => 'invalid_uses_context',
'block_hooks' => 'invalid_block_hooks',
'category' => true,
'editor_script' => true,
'script' => true,
Expand Down Expand Up @@ -244,6 +246,7 @@ public function test_get_item_invalid() {
$data['attributes']
);
$this->assertSameSets( array( 'invalid_uses_context' ), $data['uses_context'] );
$this->assertSameSets( array(), $data['block_hooks'], 'invalid block_hooks defaults to empty array' );
$this->assertSameSets( array( 'invalid_keywords' ), $data['keywords'] );
$this->assertSameSets( array( 'invalid_parent' ), $data['parent'] );
$this->assertSameSets( array( 'invalid_ancestor' ), $data['ancestor'] );
Expand All @@ -266,6 +269,7 @@ public function test_get_item_invalid() {
/**
* @ticket 47620
* @ticket 57585
* @ticket 59346
*/
public function test_get_item_defaults() {
$block_type = 'fake/false';
Expand All @@ -276,6 +280,7 @@ public function test_get_item_defaults() {
'attributes' => false,
'provides_context' => false,
'uses_context' => false,
'block_hooks' => false,
'category' => false,
'editor_script' => false,
'script' => false,
Expand Down Expand Up @@ -314,6 +319,7 @@ public function test_get_item_defaults() {
$data['attributes']
);
$this->assertSameSets( array(), $data['provides_context'] );
$this->assertSameSets( array(), $data['block_hooks'], 'block_hooks defaults to empty array' );
$this->assertSameSets( array(), $data['uses_context'] );
$this->assertSameSets( array(), $data['keywords'] );
$this->assertSameSets( array(), $data['parent'] );
Expand Down Expand Up @@ -538,14 +544,15 @@ public function test_get_variation() {
/**
* @ticket 47620
* @ticket 57585
* @ticket 59346
*/
public function test_get_item_schema() {
wp_set_current_user( self::$admin_id );
$request = new WP_REST_Request( 'OPTIONS', '/wp/v2/block-types' );
$response = rest_get_server()->dispatch( $request );
$data = $response->get_data();
$properties = $data['schema']['properties'];
$this->assertCount( 29, $properties );
$this->assertCount( 30, $properties );
$this->assertArrayHasKey( 'api_version', $properties );
$this->assertArrayHasKey( 'title', $properties );
$this->assertArrayHasKey( 'icon', $properties );
Expand All @@ -568,6 +575,7 @@ public function test_get_item_schema() {
$this->assertArrayHasKey( 'example', $properties );
$this->assertArrayHasKey( 'uses_context', $properties );
$this->assertArrayHasKey( 'provides_context', $properties );
$this->assertArrayHasKey( 'block_hooks', $properties );
$this->assertArrayHasKey( 'variations', $properties );
$this->assertArrayHasKey( 'ancestor', $properties );
// Deprecated properties.
Expand Down Expand Up @@ -664,6 +672,7 @@ public function test_prepare_item_limit_fields() {
* Util check block type object against.
*
* @since 5.5.0
* @since 6.4.0 Added the `block_hooks` extra field.
*
* @param WP_Block_Type $block_type Sample block type.
* @param array $data Data to compare against.
Expand All @@ -690,6 +699,7 @@ protected function check_block_type_object( $block_type, $data, $links ) {
'parent',
'provides_context',
'uses_context',
'block_hooks',
'supports',
'styles',
'textdomain',
Expand Down

0 comments on commit 7b90f22

Please sign in to comment.