Skip to content

Commit e800c60

Browse files
committed
Block Hooks: Suppress insertion next to post content wrapper block.
As of [59523], Block Hooks are applied to post content. In order to allow for insertion of a hooked block as `first_child` or `last_child` of the containing Post Content block, we wrap the block's post content (as obtained from the DB) in a temporary `<!-- wp:post-content -->` wrapper block, apply the Block Hooks algorithm to the resulting markup, and remove the wrapper block. (The same technique is applied for the Synced Pattern block -- see [59543] -- as well as the Navigation block.) However, this caused a problem when a hooked block was marked for insertion before `before` or `after` a Post Content block: The logic that's supposed to remove the temporary wrapper block after the Block Hooks algorithm runs erroneously removed that hooked block's delimiter instead of the wrapper block, producing garbled markup as a result. This changeset fixes the issue by adding a `hooked_block_types` filter (with `PHP_INT_MAX` priority) that removes any blocks hooked `before` or `after` a Post Content block, ''if'' the current context is a post object. This prevents any blocks hooked that way from being "absorbed" into the corresponding post object's content; it retains the ability to hook blocks `before` and `after` a Post Content block in any other context (e.g. a template). (The same principle is applied to Synced Pattern and Navigation blocks.) Props obenland, jorbin, gziolo, bernhard-reiter. Fixes #63287. git-svn-id: https://develop.svn.wordpress.org/trunk@60173 602fd350-edb4-49c9-b593-d223f7449a82
1 parent ec5bf32 commit e800c60

File tree

3 files changed

+65
-5
lines changed

3 files changed

+65
-5
lines changed

src/wp-includes/blocks.php

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1248,8 +1248,25 @@ function apply_block_hooks_to_content_from_post_object( $content, $post = null,
12481248
$content
12491249
);
12501250

1251+
/*
1252+
* We need to avoid inserting any blocks hooked into the `before` and `after` positions
1253+
* of the temporary wrapper block that we create to wrap the content.
1254+
* See https://core.trac.wordpress.org/ticket/63287 for more details.
1255+
*/
1256+
$suppress_blocks_from_insertion_before_and_after_wrapper_block = static function ( $hooked_block_types, $relative_position, $anchor_block_type ) use ( $wrapper_block_type ) {
1257+
if (
1258+
$wrapper_block_type === $anchor_block_type &&
1259+
in_array( $relative_position, array( 'before', 'after' ), true )
1260+
) {
1261+
return array();
1262+
}
1263+
return $hooked_block_types;
1264+
};
1265+
12511266
// Apply Block Hooks.
1267+
add_filter( 'hooked_block_types', $suppress_blocks_from_insertion_before_and_after_wrapper_block, PHP_INT_MAX, 3 );
12521268
$content = apply_block_hooks_to_content( $content, $post, $callback );
1269+
remove_filter( 'hooked_block_types', $suppress_blocks_from_insertion_before_and_after_wrapper_block, PHP_INT_MAX );
12531270

12541271
// Finally, we need to remove the temporary wrapper block.
12551272
$content = remove_serialized_parent_block( $content );

tests/phpunit/tests/blocks/applyBlockHooksToContent.php

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,14 @@ class Tests_Blocks_ApplyBlockHooksToContent extends WP_UnitTestCase {
1717
* Set up.
1818
*
1919
* @ticket 61902.
20+
* @ticket 63287.
2021
*/
2122
public static function wpSetUpBeforeClass() {
2223
register_block_type(
2324
'tests/hooked-block',
2425
array(
2526
'block_hooks' => array(
26-
'tests/anchor-block' => 'after',
27+
'core/post-content' => 'after',
2728
),
2829
)
2930
);
@@ -79,23 +80,25 @@ public function test_apply_block_hooks_to_content_sets_theme_attribute_on_templa
7980

8081
/**
8182
* @ticket 61902
83+
* @ticket 63287
8284
*/
8385
public function test_apply_block_hooks_to_content_inserts_hooked_block() {
8486
$context = new WP_Block_Template();
85-
$context->content = '<!-- wp:tests/anchor-block /-->';
87+
$context->content = '<!-- wp:post-content /-->';
8688

8789
$actual = apply_block_hooks_to_content( $context->content, $context, 'insert_hooked_blocks' );
8890
$this->assertSame(
89-
'<!-- wp:tests/anchor-block /--><!-- wp:tests/hooked-block /-->',
91+
'<!-- wp:post-content /--><!-- wp:tests/hooked-block /-->',
9092
$actual
9193
);
9294
}
9395

9496
/**
9597
* @ticket 61074
98+
* @ticket 63287
9699
*/
97100
public function test_apply_block_hooks_to_content_with_context_set_to_null() {
98-
$content = '<!-- wp:tests/anchor-block /-->';
101+
$content = '<!-- wp:post-content /-->';
99102

100103
/*
101104
* apply_block_hooks_to_content() will fall back to the global $post object (via get_post())
@@ -106,7 +109,7 @@ public function test_apply_block_hooks_to_content_with_context_set_to_null() {
106109

107110
$actual = apply_block_hooks_to_content( $content, null, 'insert_hooked_blocks' );
108111
$this->assertSame(
109-
'<!-- wp:tests/anchor-block /--><!-- wp:tests/hooked-block /-->',
112+
'<!-- wp:post-content /--><!-- wp:tests/hooked-block /-->',
110113
$actual
111114
);
112115
}

tests/phpunit/tests/blocks/applyBlockHooksToContentFromPostObject.php

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,17 @@ public static function wpSetUpBeforeClass() {
8888
),
8989
)
9090
);
91+
92+
register_block_type(
93+
'tests/hooked-block-after-post-content',
94+
array(
95+
'block_hooks' => array(
96+
'core/post-content' => 'after',
97+
),
98+
)
99+
);
100+
101+
register_block_type( 'tests/dynamically-hooked-block-before-post-content' );
91102
}
92103

93104
/**
@@ -100,6 +111,8 @@ public static function wpTearDownAfterClass() {
100111

101112
$registry->unregister( 'tests/hooked-block' );
102113
$registry->unregister( 'tests/hooked-block-first-child' );
114+
$registry->unregister( 'tests/hooked-block-after-post-content' );
115+
$registry->unregister( 'tests/dynamically-hooked-block-before-post-content' );
103116
}
104117

105118
/**
@@ -130,6 +143,33 @@ public function test_apply_block_hooks_to_content_from_post_object_respects_igno
130143
$this->assertSame( $expected, $actual );
131144
}
132145

146+
/**
147+
* @ticket 63287
148+
*/
149+
public function test_apply_block_hooks_to_content_from_post_object_does_not_insert_hooked_block_before_container_block() {
150+
$filter = function ( $hooked_block_types, $relative_position, $anchor_block_type ) {
151+
if ( 'core/post-content' === $anchor_block_type && 'before' === $relative_position ) {
152+
$hooked_block_types[] = 'tests/dynamically-hooked-block-before-post-content';
153+
}
154+
155+
return $hooked_block_types;
156+
};
157+
158+
$expected = '<!-- wp:tests/hooked-block-first-child /-->' .
159+
self::$post->post_content .
160+
'<!-- wp:tests/hooked-block /-->';
161+
162+
add_filter( 'hooked_block_types', $filter, 10, 3 );
163+
$actual = apply_block_hooks_to_content_from_post_object(
164+
self::$post->post_content,
165+
self::$post,
166+
'insert_hooked_blocks'
167+
);
168+
remove_filter( 'hooked_block_types', $filter, 10 );
169+
170+
$this->assertSame( $expected, $actual );
171+
}
172+
133173
/**
134174
* @ticket 62716
135175
*/

0 commit comments

Comments
 (0)