From 235e8512ed4894fbbf9c691e7b659a5e22fa0d66 Mon Sep 17 00:00:00 2001 From: Bernie Reiter Date: Tue, 28 Jan 2025 14:36:26 +0100 Subject: [PATCH 01/15] Block Hooks: Repurpose GB compat function --- lib/compat/wordpress-6.8/blocks.php | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/lib/compat/wordpress-6.8/blocks.php b/lib/compat/wordpress-6.8/blocks.php index 6cfa98691020ef..ad16e6b5c59257 100644 --- a/lib/compat/wordpress-6.8/blocks.php +++ b/lib/compat/wordpress-6.8/blocks.php @@ -5,11 +5,13 @@ * @package gutenberg */ -function gutenberg_apply_block_hooks_to_post_content( $content ) { - // The `the_content` filter does not provide the post that the content is coming from. - // However, we can infer it by calling `get_post()`, which will return the current post - // if no post ID is provided. - return apply_block_hooks_to_content( $content, get_post(), 'insert_hooked_blocks' ); +function gutenberg_apply_block_hooks_to_post_content( $content, $context = null, $callback = 'insert_hooked_blocks' ) { + // Default to the current post if no context is provided. + if ( null === $context ) { + $context = get_post(); + } + + return apply_block_hooks_to_content( $content, $context, $callback ); } // We need to apply this filter before `do_blocks` (which is hooked to `the_content` at priority 9). add_filter( 'the_content', 'gutenberg_apply_block_hooks_to_post_content', 8 ); From 2c18d636b2d6f90ced2b5f35c2d2f425a935998a Mon Sep 17 00:00:00 2001 From: Bernie Reiter Date: Tue, 28 Jan 2025 14:59:12 +0100 Subject: [PATCH 02/15] Block Hooks: Absorb temporary wrapper block functionality into apply_block_hooks_to_content --- lib/compat/wordpress-6.8/blocks.php | 42 ++++++++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/lib/compat/wordpress-6.8/blocks.php b/lib/compat/wordpress-6.8/blocks.php index ad16e6b5c59257..e1195f22bd5ba7 100644 --- a/lib/compat/wordpress-6.8/blocks.php +++ b/lib/compat/wordpress-6.8/blocks.php @@ -11,7 +11,47 @@ function gutenberg_apply_block_hooks_to_post_content( $content, $context = null, $context = get_post(); } - return apply_block_hooks_to_content( $content, $context, $callback ); + if ( ! $context instanceof WP_Post ) { + return apply_block_hooks_to_content( $content, $context, $callback ); + } + + $attributes = array(); + + // If context is a post object, `ignoredHookedBlocks` information is stored in its post meta. + $ignored_hooked_blocks = get_post_meta( $context->ID, '_wp_ignored_hooked_blocks', true ); + if ( ! empty( $ignored_hooked_blocks ) ) { + $ignored_hooked_blocks = json_decode( $ignored_hooked_blocks, true ); + $attributes['metadata'] = array( + 'ignoredHookedBlocks' => $ignored_hooked_blocks, + ); + } + + // We need to wrap the content in a temporary wrapper block with that metadata + // so the Block Hooks algorithm can insert blocks that are hooked as first or last child + // of the wrapper block. + // To that end, we need to determine the wrapper block type based on the post type. + + if ( 'wp_navigation' === $context->post_type ) { + $wrapper_block_type = 'core/navigation'; + } elseif ( 'wp_block' === $context->post_type ) { + $wrapper_block_type = 'core/block'; + } else { + $wrapper_block_type = 'core/post-content'; + } + + $content = get_comment_delimited_block_content( + $wrapper_block_type, + $attributes, + $content + ); + + // Apply Block Hooks. + $content = apply_block_hooks_to_content( $content, $context, $callback ); + + // Finally, we need to remove the temporary wrapper block. + $content = remove_serialized_parent_block( $content ); + + return $content; } // We need to apply this filter before `do_blocks` (which is hooked to `the_content` at priority 9). add_filter( 'the_content', 'gutenberg_apply_block_hooks_to_post_content', 8 ); From ab0499504ed4b5a2eb61261872a5d68a2fb8a2c2 Mon Sep 17 00:00:00 2001 From: Bernie Reiter Date: Tue, 28 Jan 2025 15:08:12 +0100 Subject: [PATCH 03/15] Remove now-obsolete logic from Post Content block --- .../block-library/src/post-content/index.php | 23 ------------------- 1 file changed, 23 deletions(-) diff --git a/packages/block-library/src/post-content/index.php b/packages/block-library/src/post-content/index.php index e0a06b7217eebe..25be880cc47887 100644 --- a/packages/block-library/src/post-content/index.php +++ b/packages/block-library/src/post-content/index.php @@ -46,33 +46,10 @@ function render_block_core_post_content( $attributes, $content, $block ) { $content .= wp_link_pages( array( 'echo' => 0 ) ); } - $ignored_hooked_blocks = get_post_meta( $post_id, '_wp_ignored_hooked_blocks', true ); - if ( ! empty( $ignored_hooked_blocks ) ) { - $ignored_hooked_blocks = json_decode( $ignored_hooked_blocks, true ); - $attributes['metadata'] = array( - 'ignoredHookedBlocks' => $ignored_hooked_blocks, - ); - } - - // Wrap in Post Content block so the Block Hooks algorithm can insert blocks - // that are hooked as first or last child of `core/post-content`. - $content = get_comment_delimited_block_content( - 'core/post-content', - $attributes, - $content - ); - - // We need to remove the `core/post-content` block wrapper after the Block Hooks algorithm, - // but before `do_blocks` runs, as it would otherwise attempt to render the same block again -- - // thus recursing infinitely. - add_filter( 'the_content', 'remove_serialized_parent_block', 8 ); - /** This filter is documented in wp-includes/post-template.php */ $content = apply_filters( 'the_content', str_replace( ']]>', ']]>', $content ) ); unset( $seen_ids[ $post_id ] ); - remove_filter( 'the_content', 'remove_serialized_parent_block', 8 ); - if ( empty( $content ) ) { return ''; } From 508c116d98ccae181f6e4a4f617cb982d7411f43 Mon Sep 17 00:00:00 2001 From: Bernie Reiter Date: Tue, 28 Jan 2025 15:08:41 +0100 Subject: [PATCH 04/15] Remove now-obsolete logic from Synced Pattern block --- packages/block-library/src/block/index.php | 19 +------------------ 1 file changed, 1 insertion(+), 18 deletions(-) diff --git a/packages/block-library/src/block/index.php b/packages/block-library/src/block/index.php index e8075115cabda4..b259e727b933af 100644 --- a/packages/block-library/src/block/index.php +++ b/packages/block-library/src/block/index.php @@ -87,25 +87,8 @@ function render_block_core_block( $attributes ) { add_filter( 'render_block_context', $filter_block_context, 1 ); } - $ignored_hooked_blocks = get_post_meta( $attributes['ref'], '_wp_ignored_hooked_blocks', true ); - if ( ! empty( $ignored_hooked_blocks ) ) { - $ignored_hooked_blocks = json_decode( $ignored_hooked_blocks, true ); - $attributes['metadata'] = array( - 'ignoredHookedBlocks' => $ignored_hooked_blocks, - ); - } - - // Wrap in "Block" block so the Block Hooks algorithm can insert blocks - // that are hooked as first or last child of `core/block`. - $content = get_comment_delimited_block_content( - 'core/block', - $attributes, - $content - ); // Apply Block Hooks. - $content = apply_block_hooks_to_content( $content, $reusable_block ); - // Remove block wrapper. - $content = remove_serialized_parent_block( $content ); + $content = gutenberg_apply_block_hooks_to_post_content( $content, $reusable_block ); $content = do_blocks( $content ); unset( $seen_refs[ $attributes['ref'] ] ); From 555cb7ec4398a5881a9877a54f1331e39995cd2f Mon Sep 17 00:00:00 2001 From: Bernie Reiter Date: Tue, 28 Jan 2025 15:17:52 +0100 Subject: [PATCH 05/15] Whitespace --- lib/compat/wordpress-6.8/blocks.php | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/compat/wordpress-6.8/blocks.php b/lib/compat/wordpress-6.8/blocks.php index e1195f22bd5ba7..8b7e941baa3c9c 100644 --- a/lib/compat/wordpress-6.8/blocks.php +++ b/lib/compat/wordpress-6.8/blocks.php @@ -30,7 +30,6 @@ function gutenberg_apply_block_hooks_to_post_content( $content, $context = null, // so the Block Hooks algorithm can insert blocks that are hooked as first or last child // of the wrapper block. // To that end, we need to determine the wrapper block type based on the post type. - if ( 'wp_navigation' === $context->post_type ) { $wrapper_block_type = 'core/navigation'; } elseif ( 'wp_block' === $context->post_type ) { From d0fe0eb33c5a59c1b23f2caeed9a7b2290aa3864 Mon Sep 17 00:00:00 2001 From: Bernie Reiter Date: Tue, 28 Jan 2025 15:29:59 +0100 Subject: [PATCH 06/15] Use in gutenberg_insert_hooked_blocks_into_rest_response --- lib/compat/wordpress-6.8/blocks.php | 30 ++--------------------------- 1 file changed, 2 insertions(+), 28 deletions(-) diff --git a/lib/compat/wordpress-6.8/blocks.php b/lib/compat/wordpress-6.8/blocks.php index 8b7e941baa3c9c..2d656014d387eb 100644 --- a/lib/compat/wordpress-6.8/blocks.php +++ b/lib/compat/wordpress-6.8/blocks.php @@ -70,38 +70,12 @@ function gutenberg_insert_hooked_blocks_into_rest_response( $response, $post ) { return $response; } - $attributes = array(); - $ignored_hooked_blocks = get_post_meta( $post->ID, '_wp_ignored_hooked_blocks', true ); - if ( ! empty( $ignored_hooked_blocks ) ) { - $ignored_hooked_blocks = json_decode( $ignored_hooked_blocks, true ); - $attributes['metadata'] = array( - 'ignoredHookedBlocks' => $ignored_hooked_blocks, - ); - } - - if ( 'wp_navigation' === $post->post_type ) { - $wrapper_block_type = 'core/navigation'; - } elseif ( 'wp_block' === $post->post_type ) { - $wrapper_block_type = 'core/block'; - } else { - $wrapper_block_type = 'core/post-content'; - } - - $content = get_comment_delimited_block_content( - $wrapper_block_type, - $attributes, - $response->data['content']['raw'] - ); - - $content = apply_block_hooks_to_content( - $content, + $content = gutenberg_apply_block_hooks_to_post_content( + $response->data['content']['raw'], $post, 'insert_hooked_blocks_and_set_ignored_hooked_blocks_metadata' ); - // Remove mock block wrapper. - $content = remove_serialized_parent_block( $content ); - $response->data['content']['raw'] = $content; // If the rendered content was previously empty, we leave it like that. From acb88e5553b79aafeae971de2f901c0fdb15a1f4 Mon Sep 17 00:00:00 2001 From: Bernie Reiter Date: Tue, 28 Jan 2025 15:31:13 +0100 Subject: [PATCH 07/15] Remove now-obsolete variable --- lib/compat/wordpress-6.8/blocks.php | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/lib/compat/wordpress-6.8/blocks.php b/lib/compat/wordpress-6.8/blocks.php index 2d656014d387eb..c7005201dae832 100644 --- a/lib/compat/wordpress-6.8/blocks.php +++ b/lib/compat/wordpress-6.8/blocks.php @@ -70,14 +70,12 @@ function gutenberg_insert_hooked_blocks_into_rest_response( $response, $post ) { return $response; } - $content = gutenberg_apply_block_hooks_to_post_content( + $response->data['content']['raw'] = gutenberg_apply_block_hooks_to_post_content( $response->data['content']['raw'], $post, 'insert_hooked_blocks_and_set_ignored_hooked_blocks_metadata' ); - $response->data['content']['raw'] = $content; - // If the rendered content was previously empty, we leave it like that. if ( empty( $response->data['content']['rendered'] ) ) { return $response; @@ -90,7 +88,10 @@ function gutenberg_insert_hooked_blocks_into_rest_response( $response, $post ) { } /** This filter is documented in wp-includes/post-template.php */ - $response->data['content']['rendered'] = apply_filters( 'the_content', $content ); + $response->data['content']['rendered'] = apply_filters( + 'the_content', + $response->data['content']['raw'] + ); // Add back the filter. if ( false !== $priority ) { From 87d8855f7158178c243713fd2bde3f3e13a129d4 Mon Sep 17 00:00:00 2001 From: Bernie Reiter Date: Tue, 28 Jan 2025 16:29:05 +0100 Subject: [PATCH 08/15] Use in Navigation block --- .../block-library/src/navigation/index.php | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/packages/block-library/src/navigation/index.php b/packages/block-library/src/navigation/index.php index 43ca8331534275..bbbc2fce587c00 100644 --- a/packages/block-library/src/navigation/index.php +++ b/packages/block-library/src/navigation/index.php @@ -241,11 +241,12 @@ private static function get_inner_blocks_from_navigation_post( $attributes ) { // it encounters whitespace. This code strips it. $blocks = block_core_navigation_filter_out_empty_blocks( $parsed_blocks ); - // Run Block Hooks algorithm to inject hooked blocks. - $markup = block_core_navigation_insert_hooked_blocks( $blocks, $navigation_post ); - $root_nav_block = parse_blocks( $markup )[0]; - - $blocks = isset( $root_nav_block['innerBlocks'] ) ? $root_nav_block['innerBlocks'] : $blocks; + // Re-serialize, and run Block Hooks algorithm to inject hooked blocks. + // TODO: See if we can move the gutenberg_apply_block_hooks_to_post_content() call + // before the parse_blocks() call further above, to avoid the extra serialization/parsing. + $markup = serialize_blocks( $blocks ); + $markup = gutenberg_apply_block_hooks_to_post_content( $markup, $navigation_post ); + $blocks = parse_blocks( $markup ); // TODO - this uses the full navigation block attributes for the // context which could be refined. @@ -1077,12 +1078,11 @@ function block_core_navigation_get_fallback_blocks() { // Run Block Hooks algorithm to inject hooked blocks. // We have to run it here because we need the post ID of the Navigation block to track ignored hooked blocks. - $markup = block_core_navigation_insert_hooked_blocks( $fallback_blocks, $navigation_post ); - $blocks = parse_blocks( $markup ); - - if ( isset( $blocks[0]['innerBlocks'] ) ) { - $fallback_blocks = $blocks[0]['innerBlocks']; - } + // TODO: See if we can move the gutenberg_apply_block_hooks_to_post_content() call + // before the parse_blocks() call further above, to avoid the extra serialization/parsing. + $markup = serialize_blocks( $fallback_blocks ); + $markup = gutenberg_apply_block_hooks_to_post_content( $markup, $navigation_post ); + $fallback_blocks = parse_blocks( $markup ); } /** From 59d943190de82d6934d3432e24a641dee576262d Mon Sep 17 00:00:00 2001 From: Bernie Reiter Date: Tue, 28 Jan 2025 16:31:20 +0100 Subject: [PATCH 09/15] Navigation block: Remove now-obsolete Block Hooks helpers --- .../block-library/src/navigation/index.php | 58 ------------------- 1 file changed, 58 deletions(-) diff --git a/packages/block-library/src/navigation/index.php b/packages/block-library/src/navigation/index.php index bbbc2fce587c00..77ba65bf71e9cd 100644 --- a/packages/block-library/src/navigation/index.php +++ b/packages/block-library/src/navigation/index.php @@ -1436,61 +1436,3 @@ function block_core_navigation_get_most_recently_published_navigation() { return null; } - -/** - * Mock a parsed block for the Navigation block given its inner blocks and the `wp_navigation` post object. - * The `wp_navigation` post's `_wp_ignored_hooked_blocks` meta is queried to add the `metadata.ignoredHookedBlocks` attribute. - * - * @since 6.5.0 - * - * @param array $inner_blocks Parsed inner blocks of a Navigation block. - * @param WP_Post $post `wp_navigation` post object corresponding to the block. - * - * @return array the normalized parsed blocks. - */ -function block_core_navigation_mock_parsed_block( $inner_blocks, $post ) { - $attributes = array(); - - if ( isset( $post->ID ) ) { - $ignored_hooked_blocks = get_post_meta( $post->ID, '_wp_ignored_hooked_blocks', true ); - if ( ! empty( $ignored_hooked_blocks ) ) { - $ignored_hooked_blocks = json_decode( $ignored_hooked_blocks, true ); - $attributes['metadata'] = array( - 'ignoredHookedBlocks' => $ignored_hooked_blocks, - ); - } - } - - $mock_anchor_parent_block = array( - 'blockName' => 'core/navigation', - 'attrs' => $attributes, - 'innerBlocks' => $inner_blocks, - 'innerContent' => array_fill( 0, count( $inner_blocks ), null ), - ); - - return $mock_anchor_parent_block; -} - -/** - * Insert hooked blocks into a Navigation block. - * - * Given a Navigation block's inner blocks and its corresponding `wp_navigation` post object, - * this function inserts hooked blocks into it, and returns the serialized inner blocks in a - * mock Navigation block wrapper. - * - * If there are any hooked blocks that need to be inserted as the Navigation block's first or last - * children, the `wp_navigation` post's `_wp_ignored_hooked_blocks` meta is checked to see if any - * of those hooked blocks should be exempted from insertion. - * - * @since 6.5.0 - * - * @param array $inner_blocks Parsed inner blocks of a Navigation block. - * @param WP_Post $post `wp_navigation` post object corresponding to the block. - * @return string Serialized inner blocks in mock Navigation block wrapper, with hooked blocks inserted, if any. - */ -function block_core_navigation_insert_hooked_blocks( $inner_blocks, $post ) { - $mock_navigation_block = block_core_navigation_mock_parsed_block( $inner_blocks, $post ); - - $mock_navigation_block_markup = serialize_block( $mock_navigation_block ); - return apply_block_hooks_to_content( $mock_navigation_block_markup, $post, 'insert_hooked_blocks' ); -} From fb934223ebf1f5bee3fa58799e9d6916da966b3c Mon Sep 17 00:00:00 2001 From: Bernie Reiter Date: Wed, 29 Jan 2025 11:08:49 +0100 Subject: [PATCH 10/15] Rename function --- lib/compat/wordpress-6.8/blocks.php | 84 ++++++++++--------- packages/block-library/src/block/index.php | 2 +- .../block-library/src/navigation/index.php | 8 +- 3 files changed, 48 insertions(+), 46 deletions(-) diff --git a/lib/compat/wordpress-6.8/blocks.php b/lib/compat/wordpress-6.8/blocks.php index c7005201dae832..2faa3de887c02a 100644 --- a/lib/compat/wordpress-6.8/blocks.php +++ b/lib/compat/wordpress-6.8/blocks.php @@ -5,55 +5,57 @@ * @package gutenberg */ -function gutenberg_apply_block_hooks_to_post_content( $content, $context = null, $callback = 'insert_hooked_blocks' ) { - // Default to the current post if no context is provided. - if ( null === $context ) { - $context = get_post(); - } +if ( ! function_exists( 'apply_block_hooks_to_content_from_post_object' ) ) { + function apply_block_hooks_to_content_from_post_object( $content, $context = null, $callback = 'insert_hooked_blocks' ) { + // Default to the current post if no context is provided. + if ( null === $context ) { + $context = get_post(); + } - if ( ! $context instanceof WP_Post ) { - return apply_block_hooks_to_content( $content, $context, $callback ); - } + if ( ! $context instanceof WP_Post ) { + return apply_block_hooks_to_content( $content, $context, $callback ); + } - $attributes = array(); + $attributes = array(); - // If context is a post object, `ignoredHookedBlocks` information is stored in its post meta. - $ignored_hooked_blocks = get_post_meta( $context->ID, '_wp_ignored_hooked_blocks', true ); - if ( ! empty( $ignored_hooked_blocks ) ) { - $ignored_hooked_blocks = json_decode( $ignored_hooked_blocks, true ); - $attributes['metadata'] = array( - 'ignoredHookedBlocks' => $ignored_hooked_blocks, - ); - } + // If context is a post object, `ignoredHookedBlocks` information is stored in its post meta. + $ignored_hooked_blocks = get_post_meta( $context->ID, '_wp_ignored_hooked_blocks', true ); + if ( ! empty( $ignored_hooked_blocks ) ) { + $ignored_hooked_blocks = json_decode( $ignored_hooked_blocks, true ); + $attributes['metadata'] = array( + 'ignoredHookedBlocks' => $ignored_hooked_blocks, + ); + } - // We need to wrap the content in a temporary wrapper block with that metadata - // so the Block Hooks algorithm can insert blocks that are hooked as first or last child - // of the wrapper block. - // To that end, we need to determine the wrapper block type based on the post type. - if ( 'wp_navigation' === $context->post_type ) { - $wrapper_block_type = 'core/navigation'; - } elseif ( 'wp_block' === $context->post_type ) { - $wrapper_block_type = 'core/block'; - } else { - $wrapper_block_type = 'core/post-content'; - } + // We need to wrap the content in a temporary wrapper block with that metadata + // so the Block Hooks algorithm can insert blocks that are hooked as first or last child + // of the wrapper block. + // To that end, we need to determine the wrapper block type based on the post type. + if ( 'wp_navigation' === $context->post_type ) { + $wrapper_block_type = 'core/navigation'; + } elseif ( 'wp_block' === $context->post_type ) { + $wrapper_block_type = 'core/block'; + } else { + $wrapper_block_type = 'core/post-content'; + } - $content = get_comment_delimited_block_content( - $wrapper_block_type, - $attributes, - $content - ); + $content = get_comment_delimited_block_content( + $wrapper_block_type, + $attributes, + $content + ); - // Apply Block Hooks. - $content = apply_block_hooks_to_content( $content, $context, $callback ); + // Apply Block Hooks. + $content = apply_block_hooks_to_content( $content, $context, $callback ); - // Finally, we need to remove the temporary wrapper block. - $content = remove_serialized_parent_block( $content ); + // Finally, we need to remove the temporary wrapper block. + $content = remove_serialized_parent_block( $content ); - return $content; + return $content; + } + // We need to apply this filter before `do_blocks` (which is hooked to `the_content` at priority 9). + add_filter( 'the_content', 'apply_block_hooks_to_content_from_post_object', 8 ); } -// We need to apply this filter before `do_blocks` (which is hooked to `the_content` at priority 9). -add_filter( 'the_content', 'gutenberg_apply_block_hooks_to_post_content', 8 ); /** * Hooks into the REST API response for the Posts endpoint and adds the first and last inner blocks. @@ -70,7 +72,7 @@ function gutenberg_insert_hooked_blocks_into_rest_response( $response, $post ) { return $response; } - $response->data['content']['raw'] = gutenberg_apply_block_hooks_to_post_content( + $response->data['content']['raw'] = apply_block_hooks_to_content_from_post_object( $response->data['content']['raw'], $post, 'insert_hooked_blocks_and_set_ignored_hooked_blocks_metadata' diff --git a/packages/block-library/src/block/index.php b/packages/block-library/src/block/index.php index b259e727b933af..94df5d5df6c077 100644 --- a/packages/block-library/src/block/index.php +++ b/packages/block-library/src/block/index.php @@ -88,7 +88,7 @@ function render_block_core_block( $attributes ) { } // Apply Block Hooks. - $content = gutenberg_apply_block_hooks_to_post_content( $content, $reusable_block ); + $content = apply_block_hooks_to_content_from_post_object( $content, $reusable_block ); $content = do_blocks( $content ); unset( $seen_refs[ $attributes['ref'] ] ); diff --git a/packages/block-library/src/navigation/index.php b/packages/block-library/src/navigation/index.php index 77ba65bf71e9cd..d52b67b7e1958c 100644 --- a/packages/block-library/src/navigation/index.php +++ b/packages/block-library/src/navigation/index.php @@ -242,10 +242,10 @@ private static function get_inner_blocks_from_navigation_post( $attributes ) { $blocks = block_core_navigation_filter_out_empty_blocks( $parsed_blocks ); // Re-serialize, and run Block Hooks algorithm to inject hooked blocks. - // TODO: See if we can move the gutenberg_apply_block_hooks_to_post_content() call + // TODO: See if we can move the apply_block_hooks_to_content_from_post_object() call // before the parse_blocks() call further above, to avoid the extra serialization/parsing. $markup = serialize_blocks( $blocks ); - $markup = gutenberg_apply_block_hooks_to_post_content( $markup, $navigation_post ); + $markup = apply_block_hooks_to_content_from_post_object( $markup, $navigation_post ); $blocks = parse_blocks( $markup ); // TODO - this uses the full navigation block attributes for the @@ -1078,10 +1078,10 @@ function block_core_navigation_get_fallback_blocks() { // Run Block Hooks algorithm to inject hooked blocks. // We have to run it here because we need the post ID of the Navigation block to track ignored hooked blocks. - // TODO: See if we can move the gutenberg_apply_block_hooks_to_post_content() call + // TODO: See if we can move the apply_block_hooks_to_content_from_post_object() call // before the parse_blocks() call further above, to avoid the extra serialization/parsing. $markup = serialize_blocks( $fallback_blocks ); - $markup = gutenberg_apply_block_hooks_to_post_content( $markup, $navigation_post ); + $markup = apply_block_hooks_to_content_from_post_object( $markup, $navigation_post ); $fallback_blocks = parse_blocks( $markup ); } From b4a070d78fc9a69931955888f48be89d397b2421 Mon Sep 17 00:00:00 2001 From: Bernie Reiter Date: Wed, 29 Jan 2025 11:31:14 +0100 Subject: [PATCH 11/15] Replace filters correctly --- lib/compat/wordpress-6.8/blocks.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/lib/compat/wordpress-6.8/blocks.php b/lib/compat/wordpress-6.8/blocks.php index 2faa3de887c02a..aa1bc58a5893ef 100644 --- a/lib/compat/wordpress-6.8/blocks.php +++ b/lib/compat/wordpress-6.8/blocks.php @@ -55,6 +55,8 @@ function apply_block_hooks_to_content_from_post_object( $content, $context = nul } // We need to apply this filter before `do_blocks` (which is hooked to `the_content` at priority 9). add_filter( 'the_content', 'apply_block_hooks_to_content_from_post_object', 8 ); + // Remove apply_block_hooks_to_content filter (previously added in Core). + remove_filter( 'the_content', 'apply_block_hooks_to_content', 8 ); } /** @@ -84,9 +86,9 @@ function gutenberg_insert_hooked_blocks_into_rest_response( $response, $post ) { } // No need to inject hooked blocks twice. - $priority = has_filter( 'the_content', 'apply_block_hooks_to_content' ); + $priority = has_filter( 'the_content', 'apply_block_hooks_to_content_from_post_object' ); if ( false !== $priority ) { - remove_filter( 'the_content', 'apply_block_hooks_to_content', $priority ); + remove_filter( 'the_content', 'apply_block_hooks_to_content_from_post_object', $priority ); } /** This filter is documented in wp-includes/post-template.php */ @@ -97,7 +99,7 @@ function gutenberg_insert_hooked_blocks_into_rest_response( $response, $post ) { // Add back the filter. if ( false !== $priority ) { - add_filter( 'the_content', 'apply_block_hooks_to_content', $priority ); + add_filter( 'the_content', 'apply_block_hooks_to_content_from_post_object', $priority ); } return $response; From 1950380d9d3e1ddb24ebddaccde0d001a9736a07 Mon Sep 17 00:00:00 2001 From: Bernie Reiter Date: Wed, 29 Jan 2025 14:16:00 +0100 Subject: [PATCH 12/15] Rename context to post --- lib/compat/wordpress-6.8/blocks.php | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/lib/compat/wordpress-6.8/blocks.php b/lib/compat/wordpress-6.8/blocks.php index aa1bc58a5893ef..71f986825a8d9c 100644 --- a/lib/compat/wordpress-6.8/blocks.php +++ b/lib/compat/wordpress-6.8/blocks.php @@ -6,20 +6,20 @@ */ if ( ! function_exists( 'apply_block_hooks_to_content_from_post_object' ) ) { - function apply_block_hooks_to_content_from_post_object( $content, $context = null, $callback = 'insert_hooked_blocks' ) { + function apply_block_hooks_to_content_from_post_object( $content, $post = null, $callback = 'insert_hooked_blocks' ) { // Default to the current post if no context is provided. - if ( null === $context ) { - $context = get_post(); + if ( null === $post ) { + $post = get_post(); } - if ( ! $context instanceof WP_Post ) { - return apply_block_hooks_to_content( $content, $context, $callback ); + if ( ! $post instanceof WP_Post ) { + return apply_block_hooks_to_content( $content, $post, $callback ); } $attributes = array(); // If context is a post object, `ignoredHookedBlocks` information is stored in its post meta. - $ignored_hooked_blocks = get_post_meta( $context->ID, '_wp_ignored_hooked_blocks', true ); + $ignored_hooked_blocks = get_post_meta( $post->ID, '_wp_ignored_hooked_blocks', true ); if ( ! empty( $ignored_hooked_blocks ) ) { $ignored_hooked_blocks = json_decode( $ignored_hooked_blocks, true ); $attributes['metadata'] = array( @@ -31,9 +31,9 @@ function apply_block_hooks_to_content_from_post_object( $content, $context = nul // so the Block Hooks algorithm can insert blocks that are hooked as first or last child // of the wrapper block. // To that end, we need to determine the wrapper block type based on the post type. - if ( 'wp_navigation' === $context->post_type ) { + if ( 'wp_navigation' === $post->post_type ) { $wrapper_block_type = 'core/navigation'; - } elseif ( 'wp_block' === $context->post_type ) { + } elseif ( 'wp_block' === $post->post_type ) { $wrapper_block_type = 'core/block'; } else { $wrapper_block_type = 'core/post-content'; @@ -46,7 +46,7 @@ function apply_block_hooks_to_content_from_post_object( $content, $context = nul ); // Apply Block Hooks. - $content = apply_block_hooks_to_content( $content, $context, $callback ); + $content = apply_block_hooks_to_content( $content, $post, $callback ); // Finally, we need to remove the temporary wrapper block. $content = remove_serialized_parent_block( $content ); From 558cb7415498ff83c249fac8950065f8e93cef84 Mon Sep 17 00:00:00 2001 From: Bernie Reiter Date: Wed, 29 Jan 2025 14:16:21 +0100 Subject: [PATCH 13/15] Add type annotation --- lib/compat/wordpress-6.8/blocks.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/compat/wordpress-6.8/blocks.php b/lib/compat/wordpress-6.8/blocks.php index 71f986825a8d9c..645bb0233c48be 100644 --- a/lib/compat/wordpress-6.8/blocks.php +++ b/lib/compat/wordpress-6.8/blocks.php @@ -6,7 +6,7 @@ */ if ( ! function_exists( 'apply_block_hooks_to_content_from_post_object' ) ) { - function apply_block_hooks_to_content_from_post_object( $content, $post = null, $callback = 'insert_hooked_blocks' ) { + function apply_block_hooks_to_content_from_post_object( $content, WP_Post $post = null, $callback = 'insert_hooked_blocks' ) { // Default to the current post if no context is provided. if ( null === $post ) { $post = get_post(); From e0e001e7c3a8706955d396324bce66e815aa5ee7 Mon Sep 17 00:00:00 2001 From: Bernie Reiter Date: Wed, 29 Jan 2025 15:33:15 +0100 Subject: [PATCH 14/15] Add PHPDoc --- lib/compat/wordpress-6.8/blocks.php | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/lib/compat/wordpress-6.8/blocks.php b/lib/compat/wordpress-6.8/blocks.php index 645bb0233c48be..90be78cd1457fb 100644 --- a/lib/compat/wordpress-6.8/blocks.php +++ b/lib/compat/wordpress-6.8/blocks.php @@ -6,6 +6,26 @@ */ if ( ! function_exists( 'apply_block_hooks_to_content_from_post_object' ) ) { + /** + * Run the Block Hooks algorithm on a post object's content. + * + * This function is different from `apply_block_hooks_to_content` in that + * it takes ignored hooked block information from the post's metadata into + * account. This ensures that any blocks hooked as first or last child + * of the block that corresponds to the post type are handled correctly. + * + * @since 6.8.0 + * @access private + * + * @param string $content Serialized content. + * @param WP_Post|null $post A post object that the content belongs to. If set to `null`, + * `get_post()` will be called to use the current post as context. + * Default: `null`. + * @param callable $callback A function that will be called for each block to generate + * the markup for a given list of blocks that are hooked to it. + * Default: 'insert_hooked_blocks'. + * @return string The serialized markup. + */ function apply_block_hooks_to_content_from_post_object( $content, WP_Post $post = null, $callback = 'insert_hooked_blocks' ) { // Default to the current post if no context is provided. if ( null === $post ) { From 8d1e6543a8fe9f43f50144b968842ba613667a3f Mon Sep 17 00:00:00 2001 From: Bernie Reiter Date: Wed, 29 Jan 2025 15:41:20 +0100 Subject: [PATCH 15/15] Add backport changelog --- backport-changelog/6.8/8212.md | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 backport-changelog/6.8/8212.md diff --git a/backport-changelog/6.8/8212.md b/backport-changelog/6.8/8212.md new file mode 100644 index 00000000000000..a4488d2da99f2b --- /dev/null +++ b/backport-changelog/6.8/8212.md @@ -0,0 +1,3 @@ +https://github.com/WordPress/wordpress-develop/pull/8212 + +* https://github.com/WordPress/gutenberg/pull/68926