WordPress.org

Make WordPress Core

Changeset 51894


Ignore:
Timestamp:
10/06/2021 06:47:09 PM (2 months ago)
Author:
azaozz
Message:

Apply the pre_render_block, render_block_data, and render_block_context filters when rendering inner/nested blocks. Introdices another param to these filters: $parent_block that is the "parent" WP_Block instance for nested blocks and null for top level blocks. Adds unit tests for the filters.

Props noisysocks, gaambo, azaozz.
Fixes #51612.

Location:
trunk
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/blocks.php

    r51888 r51894  
    814814function render_block( $parsed_block ) {
    815815    global $post;
     816    $parent_block = null;
    816817
    817818    /**
     
    820821     * @since 5.1.0
    821822     *
    822      * @param string|null $pre_render   The pre-rendered content. Default null.
    823      * @param array       $parsed_block The block being rendered.
     823     * @param string|null   $pre_render   The pre-rendered content. Default null.
     824     * @param array         $parsed_block The block being rendered.
     825     * @param WP_Block|null $parent_block If this is a nested block, a reference to the parent block.
    824826     */
    825     $pre_render = apply_filters( 'pre_render_block', null, $parsed_block );
     827    $pre_render = apply_filters( 'pre_render_block', null, $parsed_block, $parent_block );
    826828    if ( ! is_null( $pre_render ) ) {
    827829        return $pre_render;
     
    835837     * @since 5.1.0
    836838     *
    837      * @param array $parsed_block The block being rendered.
    838      * @param array $source_block An un-modified copy of $parsed_block, as it appeared in the source content.
     839     * @param array         $parsed_block The block being rendered.
     840     * @param array         $source_block An un-modified copy of $parsed_block, as it appeared in the source content.
     841     * @param WP_Block|null $parent_block If this is a nested block, a reference to the parent block.
    839842     */
    840     $parsed_block = apply_filters( 'render_block_data', $parsed_block, $source_block );
     843    $parsed_block = apply_filters( 'render_block_data', $parsed_block, $source_block, $parent_block );
    841844
    842845    $context = array();
     
    859862     * @since 5.5.0
    860863     *
    861      * @param array $context      Default context.
    862      * @param array $parsed_block Block being rendered, filtered by `render_block_data`.
     864     * @param array         $context      Default context.
     865     * @param array         $parsed_block Block being rendered, filtered by `render_block_data`.
     866     * @param WP_Block|null $parent_block If this is a nested block, a reference to the parent block.
    863867     */
    864     $context = apply_filters( 'render_block_context', $context, $parsed_block );
     868    $context = apply_filters( 'render_block_context', $context, $parsed_block, $parent_block );
    865869
    866870    $block = new WP_Block( $parsed_block, $context );
  • trunk/src/wp-includes/class-wp-block.php

    r51841 r51894  
    5959
    6060    /**
     61     * Block type registry.
     62     *
     63     * @since 5.9.0
     64     * @var WP_Block_Type_Registry
     65     * @access protected
     66     */
     67    protected $registry;
     68
     69    /**
    6170     * List of inner blocks (of this same class)
    6271     *
     
    115124            $registry = WP_Block_Type_Registry::get_instance();
    116125        }
     126
     127        $this->registry = $registry;
    117128
    118129        $this->block_type = $registry->get_registered( $this->name );
     
    206217        if ( ! $options['dynamic'] || empty( $this->block_type->skip_inner_blocks ) ) {
    207218            $index = 0;
     219
    208220            foreach ( $this->inner_content as $chunk ) {
    209                 $block_content .= is_string( $chunk ) ?
    210                     $chunk :
    211                     $this->inner_blocks[ $index++ ]->render();
     221                if ( is_string( $chunk ) ) {
     222                    $block_content .= $chunk;
     223                } else {
     224                    $inner_block  = $this->inner_blocks[ $index ];
     225                    $parent_block = $this;
     226
     227                    /** This filter is documented in wp-includes/blocks.php */
     228                    $pre_render = apply_filters( 'pre_render_block', null, $inner_block->parsed_block, $parent_block );
     229
     230                    if ( ! is_null( $pre_render ) ) {
     231                        $block_content .= $pre_render;
     232                    } else {
     233                        $source_block = $inner_block->parsed_block;
     234
     235                        /** This filter is documented in wp-includes/blocks.php */
     236                        $inner_block->parsed_block = apply_filters( 'render_block_data', $inner_block->parsed_block, $source_block, $parent_block );
     237
     238                        /** This filter is documented in wp-includes/blocks.php */
     239                        $inner_block->context = apply_filters( 'render_block_context', $inner_block->context, $inner_block->parsed_block, $parent_block );
     240
     241                        $block_content .= $inner_block->render();
     242                    }
     243
     244                    $index++;
     245                }
    212246            }
    213247        }
  • trunk/tests/phpunit/tests/blocks/wpBlock.php

    r51657 r51894  
    629629        $this->assertFalse( $gradient_support );
    630630    }
     631
     632    /**
     633     * @ticket 51612
     634     */
     635    public function test_block_filters_for_inner_blocks() {
     636        $pre_render_callback           = new MockAction();
     637        $render_block_data_callback    = new MockAction();
     638        $render_block_context_callback = new MockAction();
     639
     640        $this->registry->register(
     641            'core/outer',
     642            array(
     643                'render_callback' => function( $block_attributes, $content ) {
     644                    return $content;
     645                },
     646            )
     647        );
     648
     649        $this->registry->register(
     650            'core/inner',
     651            array(
     652                'render_callback' => function() {
     653                    return 'b';
     654                },
     655            )
     656        );
     657
     658        $parsed_blocks = parse_blocks( '<!-- wp:outer -->a<!-- wp:inner /-->c<!-- /wp:outer -->' );
     659        $parsed_block  = $parsed_blocks[0];
     660
     661        add_filter( 'pre_render_block', array( $pre_render_callback, 'filter' ) );
     662        add_filter( 'render_block_data', array( $render_block_data_callback, 'filter' ) );
     663        add_filter( 'render_block_context', array( $render_block_context_callback, 'filter' ) );
     664
     665        render_block( $parsed_block );
     666
     667        $this->assertSame( 2, $pre_render_callback->get_call_count() );
     668        $this->assertSame( 2, $render_block_data_callback->get_call_count() );
     669        $this->assertSame( 2, $render_block_context_callback->get_call_count() );
     670    }
    631671}
Note: See TracChangeset for help on using the changeset viewer.