From b62b7a599e5d7241d288c8a6dcc03d48568c1a7d Mon Sep 17 00:00:00 2001 From: Bernhard Reiter Date: Mon, 3 Jun 2024 12:05:15 +0000 Subject: [PATCH] Block Hooks: Move ignoredHookedBlocks metadata injection logic. As of [57790], the Templates endpoint uses the `rest_pre_insert_*` filter to inject the `ignoredHookedBlocks` metadata attribute into anchor blocks, prior to persisting a template or template part to the database. The same principle was implemented for the Navigation endpoint (where additionally, first and last child blocks added at the top level are store in the `wp_navigation` post object's post meta). The required logic was added to the Navigation block's code, i.e. inside the Gutenberg code repository, and then synchronized to Core. In order to harmonize the code between the two endpoints, this changeset introduces a new `update_ignored_hooked_blocks_postmeta` function, which is based on the Navigation block's `block_core_navigation_update_ignore_hooked_blocks_meta`, alongside a few helper functions, and hooks it to the `rest_pre_insert_wp_navigation` filter hook. (The Navigation block has been prepared in [58275] to add an additional conditional to check for the new `update_ignored_hooked_blocks_postmeta` filter so there won't be any collisions.) Eventually, this will allow to deprecate `block_core_navigation_update_ignore_hooked_blocks_meta` (and some related functions), and remove the relevant code from the Navigation block. It also paves the way for some other future changes, such as inserting a hooked block as a Template Part block's first or last child (#60854). Props tomjcafferkey, bernhard-reiter. Fixes #60759. Built from https://develop.svn.wordpress.org/trunk@58291 git-svn-id: http://core.svn.wordpress.org/trunk@57751 1a063a9b-81f0-0310-95a4-ce76da25c4cd --- wp-includes/block-template-utils.php | 6 +- wp-includes/blocks.php | 118 ++++++++++++++++++++++++++- wp-includes/default-filters.php | 3 + wp-includes/version.php | 2 +- 4 files changed, 119 insertions(+), 10 deletions(-) diff --git a/wp-includes/block-template-utils.php b/wp-includes/block-template-utils.php index 0a404da8c6..58ee129d2a 100644 --- a/wp-includes/block-template-utils.php +++ b/wp-includes/block-template-utils.php @@ -1599,11 +1599,7 @@ function inject_ignored_hooked_blocks_metadata_attributes( $changes, $deprecated return $template; } - $before_block_visitor = make_before_block_visitor( $hooked_blocks, $template, 'set_ignored_hooked_blocks_metadata' ); - $after_block_visitor = make_after_block_visitor( $hooked_blocks, $template, 'set_ignored_hooked_blocks_metadata' ); - - $blocks = parse_blocks( $changes->post_content ); - $changes->post_content = traverse_and_serialize_blocks( $blocks, $before_block_visitor, $after_block_visitor ); + $changes->post_content = apply_block_hooks_to_content( $changes->post_content, $template, 'set_ignored_hooked_blocks_metadata' ); return $changes; } diff --git a/wp-includes/blocks.php b/wp-includes/blocks.php index e33912b617..e68eb36b4b 100644 --- a/wp-includes/blocks.php +++ b/wp-includes/blocks.php @@ -1003,14 +1003,124 @@ function set_ignored_hooked_blocks_metadata( &$parsed_anchor_block, $relative_po } /** + * Runs the hooked blocks algorithm on the given content. + * + * @since 6.6.0 + * @access private + * + * @param string $content Serialized content. + * @param WP_Block_Template|WP_Post|array $context A block template, template part, `wp_navigation` post object, + * or pattern that the blocks belong to. + * @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( $content, $context, $callback = 'insert_hooked_blocks' ) { + $hooked_blocks = get_hooked_blocks(); + if ( empty( $hooked_blocks ) && ! has_filter( 'hooked_block_types' ) ) { + return $content; + } + + $blocks = parse_blocks( $content ); + + $before_block_visitor = make_before_block_visitor( $hooked_blocks, $context, $callback ); + $after_block_visitor = make_after_block_visitor( $hooked_blocks, $context, $callback ); + + return traverse_and_serialize_blocks( $blocks, $before_block_visitor, $after_block_visitor ); +} + +/** + * Accepts the serialized markup of a block and its inner blocks, and returns serialized markup of the inner blocks. + * + * @since 6.6.0 + * @access private + * + * @param string $serialized_block The serialized markup of a block and its inner blocks. + * @return string The serialized markup of the inner blocks. + */ +function remove_serialized_parent_block( $serialized_block ) { + $start = strpos( $serialized_block, '-->' ) + strlen( '-->' ); + $end = strrpos( $serialized_block, '