Make WordPress Core

Changeset 60189


Ignore:
Timestamp:
04/25/2025 07:21:31 PM (3 weeks ago)
Author:
jorbin
Message:

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.)

Reviewed by Jorbin.
Merges [60173] to 6.8 branch.

Props obenland, jorbin, gziolo, bernhard-reiter.
Fixes #63287.

Location:
branches/6.8
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • branches/6.8

  • branches/6.8/src/wp-includes/blocks.php

    r59938 r60189  
    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.
  • branches/6.8/tests/phpunit/tests/blocks/applyBlockHooksToContent.php

    r59523 r60189  
    1818     *
    1919     * @ticket 61902.
     20     * @ticket 63287.
    2021     */
    2122    public static function wpSetUpBeforeClass() {
     
    2425            array(
    2526                'block_hooks' => array(
    26                     'tests/anchor-block' => 'after',
     27                    'core/post-content' => 'after',
    2728                ),
    2829            )
     
    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        );
     
    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        /*
     
    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        );
  • branches/6.8/tests/phpunit/tests/blocks/applyBlockHooksToContentFromPostObject.php

    r59838 r60189  
    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
     
    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
     
    132145
    133146    /**
     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
     173    /**
    134174     * @ticket 62716
    135175     */
Note: See TracChangeset for help on using the changeset viewer.