Make WordPress Core


Ignore:
Timestamp:
01/17/2025 09:35:50 PM (14 months ago)
Author:
joemcgill
Message:

Editor: Improve consistency of render_block_context filter.

This ensures that when block context is filtered via render_block_context, the filtered value is provided as available context to inner blocks.

For backwards compatibility reasons, filtered context is added to inner block context regardless of whether that block has declared support via the uses_context property.

Props mukesh27, flixos90, gziolo, dlh, joemcgill, santosguillamot.
Fixes #62046.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/tests/phpunit/tests/blocks/renderBlock.php

    r56761 r59662  
    193193        $this->assertSame( array( 'example' => 'ok' ), $provided_context[0] );
    194194    }
     195
     196    /**
     197     * Tests the behavior of the 'render_block_context' filter based on the location of the filtered block.
     198     *
     199     * @ticket 62046
     200     */
     201    public function test_render_block_context_inner_blocks() {
     202        $provided_context = array();
     203
     204        register_block_type(
     205            'tests/context-provider',
     206            array(
     207                'provides_context' => array( 'example' ),
     208            )
     209        );
     210
     211        register_block_type(
     212            'tests/context-consumer',
     213            array(
     214                'uses_context'    => array( 'example' ),
     215                'render_callback' => static function ( $attributes, $content, $block ) use ( &$provided_context ) {
     216                    $provided_context = $block->context;
     217
     218                    return '';
     219                },
     220            )
     221        );
     222
     223        // Filter the context provided by the test block.
     224        add_filter(
     225            'render_block_context',
     226            function ( $context, $parsed_block ) {
     227                if ( isset( $parsed_block['blockName'] ) && 'tests/context-provider' === $parsed_block['blockName'] ) {
     228                    $context['example'] = 'ok';
     229                }
     230
     231                return $context;
     232            },
     233            10,
     234            2
     235        );
     236
     237        // Test inner block context when the provider block is a top-level block.
     238        do_blocks(
     239            <<<HTML
     240<!-- wp:tests/context-provider -->
     241<!-- wp:tests/context-consumer /-->
     242<!-- /wp:tests/context-provider -->
     243HTML
     244        );
     245        $this->assertArrayHasKey( 'example', $provided_context, 'Test block is top-level block: Context should include "example"' );
     246        $this->assertSame( 'ok', $provided_context['example'], 'Test block is top-level block: "example" in context should be "ok"' );
     247
     248        // Test inner block context when the provider block is an inner block.
     249        do_blocks(
     250            <<<HTML
     251<!-- wp:group {"layout":{"type":"constrained"}} -->
     252<!-- wp:tests/context-provider -->
     253<!-- wp:tests/context-consumer /-->
     254<!-- /wp:tests/context-provider -->
     255<!-- /wp:group -->
     256HTML
     257        );
     258        $this->assertArrayHasKey( 'example', $provided_context, 'Test block is inner block: Block context should include "example"' );
     259        $this->assertSame( 'ok', $provided_context['example'], 'Test block is inner block: "example" in context should be "ok"' );
     260    }
     261
     262    /**
     263     * Tests that the 'render_block_context' filter arbitrary context.
     264     *
     265     * @ticket 62046
     266     */
     267    public function test_render_block_context_allowed_context() {
     268        $provided_context = array();
     269
     270        register_block_type(
     271            'tests/context-consumer',
     272            array(
     273                'uses_context'    => array( 'example' ),
     274                'render_callback' => static function ( $attributes, $content, $block ) use ( &$provided_context ) {
     275                    $provided_context = $block->context;
     276
     277                    return '';
     278                },
     279            )
     280        );
     281
     282        // Filter the context provided to the test block.
     283        add_filter(
     284            'render_block_context',
     285            function ( $context, $parsed_block ) {
     286                if ( isset( $parsed_block['blockName'] ) && 'tests/context-consumer' === $parsed_block['blockName'] ) {
     287                    $context['arbitrary'] = 'ok';
     288                }
     289
     290                return $context;
     291            },
     292            10,
     293            2
     294        );
     295
     296        do_blocks(
     297            <<<HTML
     298<!-- wp:tests/context-consumer /-->
     299HTML
     300        );
     301        $this->assertArrayNotHasKey( 'arbitrary', $provided_context, 'Test block is top-level block: Block context should not include "arbitrary"' );
     302
     303        do_blocks(
     304            <<<HTML
     305<!-- wp:group {"layout":{"type":"constrained"}} -->
     306<!-- wp:tests/context-consumer /-->
     307<!-- /wp:group -->
     308HTML
     309        );
     310
     311        /*
     312         * These assertions assert something that ideally should not be the case: Inner blocks should respect the
     313         * `uses_context` value just like top-level blocks do. However, due to logic in `WP_Block::render()`, the
     314         * `context` property value itself is filterable when it should rather only apply to the `available_context`
     315         * property.
     316         * However, changing this behavior now would be a backward compatibility break, hence the assertion here.
     317         * Potentially it can be reconsidered in the future, so that these two assertions could be replaced with an
     318         * `assertArrayNotHasKey( 'arbitrary', $provided_context )`.
     319         */
     320        $this->assertArrayHasKey( 'arbitrary', $provided_context, 'Test block is inner block: Block context should include "arbitrary"' );
     321        $this->assertSame( 'ok', $provided_context['arbitrary'], 'Test block is inner block: "arbitrary" in context should be "ok"' );
     322    }
    195323}
Note: See TracChangeset for help on using the changeset viewer.