Skip to content

Commit 7b90f22

Browse files
committed
General: Add block_hooks field to block type registration, REST API.
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
1 parent e005108 commit 7b90f22

8 files changed

Lines changed: 86 additions & 1 deletion

File tree

src/wp-admin/includes/post.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2207,6 +2207,7 @@ function taxonomy_meta_box_sanitize_cb_input( $taxonomy, $terms ) {
22072207
*
22082208
* @since 5.0.0
22092209
* @since 6.3.0 Added `selectors` field.
2210+
* @since 6.4.0 Added `block_hooks` field.
22102211
*
22112212
* @return array An associative array of registered block data.
22122213
*/
@@ -2221,6 +2222,7 @@ function get_block_editor_server_block_settings() {
22212222
'attributes' => 'attributes',
22222223
'provides_context' => 'providesContext',
22232224
'uses_context' => 'usesContext',
2225+
'block_hooks' => 'blockHooks',
22242226
'selectors' => 'selectors',
22252227
'supports' => 'supports',
22262228
'category' => 'category',

src/wp-includes/blocks.php

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,7 @@ function get_block_metadata_i18n_schema() {
342342
* @since 5.9.0 Added support for `variations` and `viewScript` fields.
343343
* @since 6.1.0 Added support for `render` field.
344344
* @since 6.3.0 Added `selectors` field.
345+
* @since 6.4.0 Added support for `blockHooks` field.
345346
*
346347
* @param string $file_or_folder Path to the JSON file with metadata definition for
347348
* the block or path to the folder where the `block.json` file is located.
@@ -513,6 +514,39 @@ function register_block_type_from_metadata( $file_or_folder, $args = array() ) {
513514
}
514515
}
515516

517+
if ( ! empty( $metadata['blockHooks'] ) ) {
518+
/**
519+
* Map camelCased position string (from block.json) to snake_cased block type position.
520+
*
521+
* @var array
522+
*/
523+
$position_mappings = array(
524+
'before' => 'before',
525+
'after' => 'after',
526+
'firstChild' => 'first_child',
527+
'lastChild' => 'last_child',
528+
);
529+
530+
$settings['block_hooks'] = array();
531+
foreach ( $metadata['blockHooks'] as $anchor_block_name => $position ) {
532+
// Avoid infinite recursion (hooking to itself).
533+
if ( $metadata['name'] === $anchor_block_name ) {
534+
_doing_it_wrong(
535+
__METHOD__,
536+
__( 'Cannot hook block to itself.', 'gutenberg' ),
537+
'6.4.0'
538+
);
539+
continue;
540+
}
541+
542+
if ( ! isset( $position_mappings[ $position ] ) ) {
543+
continue;
544+
}
545+
546+
$settings['block_hooks'][ $anchor_block_name ] = $position_mappings[ $position ];
547+
}
548+
}
549+
516550
if ( ! empty( $metadata['render'] ) ) {
517551
$template_path = wp_normalize_path(
518552
realpath(

src/wp-includes/class-wp-block-type.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,18 @@ class WP_Block_Type {
173173
*/
174174
public $provides_context = null;
175175

176+
/**
177+
* Block hooks for this block type.
178+
*
179+
* A block hook is specified by a block type and a relative position.
180+
* The hooked block will be automatically inserted in the given position
181+
* next to the "anchor" block whenever the latter is encountered.
182+
*
183+
* @since 6.4.0
184+
* @var array[]
185+
*/
186+
public $block_hooks = array();
187+
176188
/**
177189
* Block type editor only script handles.
178190
*
@@ -254,6 +266,7 @@ class WP_Block_Type {
254266
* `editor_style_handles`, and `style_handles` properties.
255267
* Deprecated the `editor_script`, `script`, `view_script`, `editor_style`, and `style` properties.
256268
* @since 6.3.0 Added the `selectors` property.
269+
* @since 6.4.0 Added the `block_hooks` property.
257270
*
258271
* @see register_block_type()
259272
*
@@ -284,6 +297,7 @@ class WP_Block_Type {
284297
* @type array|null $attributes Block type attributes property schemas.
285298
* @type string[] $uses_context Context values inherited by blocks of this type.
286299
* @type string[]|null $provides_context Context provided by blocks of this type.
300+
* @type array[] $block_hooks Block hooks.
287301
* @type string[] $editor_script_handles Block type editor only script handles.
288302
* @type string[] $script_handles Block type front end and editor script handles.
289303
* @type string[] $view_script_handles Block type front end only script handles.

src/wp-includes/rest-api/endpoints/class-wp-rest-block-types-controller.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,7 @@ public function prepare_item_for_response( $item, $request ) {
291291
'editor_style_handles',
292292
'style_handles',
293293
'variations',
294+
'block_hooks',
294295
),
295296
$deprecated_fields
296297
);
@@ -706,6 +707,19 @@ public function get_item_schema() {
706707
),
707708
'keywords' => $keywords_definition,
708709
'example' => $example_definition,
710+
'block_hooks' => array(
711+
'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.' ),
712+
'type' => 'object',
713+
'patternProperties' => array(
714+
'^[a-zA-Z0-9-]+/[a-zA-Z0-9-]+$' => array(
715+
'type' => 'string',
716+
'enum' => array( 'before', 'after', 'first_child', 'last_child' ),
717+
),
718+
),
719+
'default' => array(),
720+
'context' => array( 'embed', 'view', 'edit' ),
721+
'readonly' => true,
722+
),
709723
),
710724
);
711725

tests/phpunit/data/blocks/notice/block.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@
3030
"selectors": {
3131
"root": ".wp-block-notice"
3232
},
33+
"blockHooks": {
34+
"core/post-content": "before"
35+
},
3336
"supports": {
3437
"align": true,
3538
"lightBlockWrapper": true

tests/phpunit/tests/admin/includesPost.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -918,6 +918,7 @@ public function test_get_block_editor_server_block_settings() {
918918
'render_callback' => 'foo',
919919
'ancestor' => array( 'core/test-ancestor' ),
920920
'selectors' => array( 'root' => '.wp-block-test' ),
921+
'block_hooks' => array( 'core/post-content' => 'before' ),
921922
);
922923

923924
register_block_type( $name, $settings );
@@ -937,6 +938,7 @@ public function test_get_block_editor_server_block_settings() {
937938
'lock' => array( 'type' => 'object' ),
938939
),
939940
'usesContext' => array(),
941+
'blockHooks' => array( 'core/post-content' => 'before' ),
940942
'selectors' => array( 'root' => '.wp-block-test' ),
941943
'category' => 'common',
942944
'styles' => array(),

tests/phpunit/tests/blocks/register.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -644,6 +644,12 @@ public function test_block_registers_with_metadata_fixture() {
644644
$result->selectors,
645645
'Block type should contain selectors from metadata.'
646646
);
647+
// @ticket 59346
648+
$this->assertSame(
649+
array( 'core/post-content' => 'before' ),
650+
$result->block_hooks,
651+
'Block type should contain block hooks from metadata.'
652+
);
647653
$this->assertSame(
648654
array(
649655
'align' => true,

tests/phpunit/tests/rest-api/rest-block-type-controller.php

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,7 @@ public function test_get_block_invalid_name() {
195195
/**
196196
* @ticket 47620
197197
* @ticket 57585
198+
* @ticket 59346
198199
*/
199200
public function test_get_item_invalid() {
200201
$block_type = 'fake/invalid';
@@ -205,6 +206,7 @@ public function test_get_item_invalid() {
205206
'attributes' => 'invalid_attributes',
206207
'provides_context' => 'invalid_provides_context',
207208
'uses_context' => 'invalid_uses_context',
209+
'block_hooks' => 'invalid_block_hooks',
208210
'category' => true,
209211
'editor_script' => true,
210212
'script' => true,
@@ -244,6 +246,7 @@ public function test_get_item_invalid() {
244246
$data['attributes']
245247
);
246248
$this->assertSameSets( array( 'invalid_uses_context' ), $data['uses_context'] );
249+
$this->assertSameSets( array(), $data['block_hooks'], 'invalid block_hooks defaults to empty array' );
247250
$this->assertSameSets( array( 'invalid_keywords' ), $data['keywords'] );
248251
$this->assertSameSets( array( 'invalid_parent' ), $data['parent'] );
249252
$this->assertSameSets( array( 'invalid_ancestor' ), $data['ancestor'] );
@@ -266,6 +269,7 @@ public function test_get_item_invalid() {
266269
/**
267270
* @ticket 47620
268271
* @ticket 57585
272+
* @ticket 59346
269273
*/
270274
public function test_get_item_defaults() {
271275
$block_type = 'fake/false';
@@ -276,6 +280,7 @@ public function test_get_item_defaults() {
276280
'attributes' => false,
277281
'provides_context' => false,
278282
'uses_context' => false,
283+
'block_hooks' => false,
279284
'category' => false,
280285
'editor_script' => false,
281286
'script' => false,
@@ -314,6 +319,7 @@ public function test_get_item_defaults() {
314319
$data['attributes']
315320
);
316321
$this->assertSameSets( array(), $data['provides_context'] );
322+
$this->assertSameSets( array(), $data['block_hooks'], 'block_hooks defaults to empty array' );
317323
$this->assertSameSets( array(), $data['uses_context'] );
318324
$this->assertSameSets( array(), $data['keywords'] );
319325
$this->assertSameSets( array(), $data['parent'] );
@@ -538,14 +544,15 @@ public function test_get_variation() {
538544
/**
539545
* @ticket 47620
540546
* @ticket 57585
547+
* @ticket 59346
541548
*/
542549
public function test_get_item_schema() {
543550
wp_set_current_user( self::$admin_id );
544551
$request = new WP_REST_Request( 'OPTIONS', '/wp/v2/block-types' );
545552
$response = rest_get_server()->dispatch( $request );
546553
$data = $response->get_data();
547554
$properties = $data['schema']['properties'];
548-
$this->assertCount( 29, $properties );
555+
$this->assertCount( 30, $properties );
549556
$this->assertArrayHasKey( 'api_version', $properties );
550557
$this->assertArrayHasKey( 'title', $properties );
551558
$this->assertArrayHasKey( 'icon', $properties );
@@ -568,6 +575,7 @@ public function test_get_item_schema() {
568575
$this->assertArrayHasKey( 'example', $properties );
569576
$this->assertArrayHasKey( 'uses_context', $properties );
570577
$this->assertArrayHasKey( 'provides_context', $properties );
578+
$this->assertArrayHasKey( 'block_hooks', $properties );
571579
$this->assertArrayHasKey( 'variations', $properties );
572580
$this->assertArrayHasKey( 'ancestor', $properties );
573581
// Deprecated properties.
@@ -664,6 +672,7 @@ public function test_prepare_item_limit_fields() {
664672
* Util check block type object against.
665673
*
666674
* @since 5.5.0
675+
* @since 6.4.0 Added the `block_hooks` extra field.
667676
*
668677
* @param WP_Block_Type $block_type Sample block type.
669678
* @param array $data Data to compare against.
@@ -690,6 +699,7 @@ protected function check_block_type_object( $block_type, $data, $links ) {
690699
'parent',
691700
'provides_context',
692701
'uses_context',
702+
'block_hooks',
693703
'supports',
694704
'styles',
695705
'textdomain',

0 commit comments

Comments
 (0)