Make WordPress Core

Changeset 56620


Ignore:
Timestamp:
09/19/2023 12:48:41 PM (5 months ago)
Author:
gziolo
Message:

Blocks: Introduce a variation of serialize blocks helper with traversing

Introduces two new functions traverse_and_serialize_blocks and traverse_and_serialize_block with the additional $callback argument. It is possible to pass parent block, block index, chunk index to the callback argument.

Reverts changes applied to serialize_blocks and serialize_block in #59327 with [56557].

Props ockham, mukesh27.
See #59313.

Location:
trunk
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/block-template-utils.php

    r56578 r56620  
    610610
    611611    $blocks            = parse_blocks( $template_content );
    612     $template->content = serialize_blocks( $blocks, '_inject_theme_attribute_in_template_part_block' );
     612    $template->content = traverse_and_serialize_blocks( $blocks, '_inject_theme_attribute_in_template_part_block' );
    613613
    614614    return $template;
  • trunk/src/wp-includes/blocks.php

    r56618 r56620  
    928928 *
    929929 * @since 5.3.1
    930  * @since 6.4.0 The `$callback` parameter was added.
    931  *
    932  * @param array         $block    A representative array of a single parsed block object. See WP_Block_Parser_Block.
    933  * @param callable|null $callback Optional. Callback to run on each block in the tree before serialization. Default null.
     930 *
     931 * @param array $block A representative array of a single parsed block object. See WP_Block_Parser_Block.
    934932 * @return string String of rendered HTML.
    935933 */
    936 function serialize_block( $block, $callback = null ) {
    937     if ( is_callable( $callback ) ) {
    938         $block = call_user_func( $callback, $block );
    939     }
    940 
     934function serialize_block( $block ) {
    941935    $block_content = '';
    942936
    943937    $index = 0;
    944938    foreach ( $block['innerContent'] as $chunk ) {
    945         $block_content .= is_string( $chunk ) ? $chunk : serialize_block( $block['innerBlocks'][ $index++ ], $callback );
     939        $block_content .= is_string( $chunk ) ? $chunk : serialize_block( $block['innerBlocks'][ $index++ ] );
    946940    }
    947941
     
    962956 *
    963957 * @since 5.3.1
    964  * @since 6.4.0 The `$callback` parameter was added.
    965  *
    966  * @param array[]       $blocks   An array of representative arrays of parsed block objects. See serialize_block().
    967  * @param callable|null $callback Optional. Callback to run on each block in the tree before serialization. Default null.
     958 *
     959 * @param array[] $blocks An array of representative arrays of parsed block objects. See serialize_block().
    968960 * @return string String of rendered HTML.
    969961 */
    970 function serialize_blocks( $blocks, $callback = null ) {
     962function serialize_blocks( $blocks ) {
     963    return implode( '', array_map( 'serialize_block', $blocks ) );
     964}
     965
     966/**
     967 * Traverses the block applying transformations using the callback provided and returns the content of a block,
     968 * including comment delimiters, serializing all attributes from the given parsed block.
     969 *
     970 * This should be used when there is a need to modify the saved block.
     971 * Prefer `serialize_block` when preparing a block to be saved to post content.
     972 *
     973 * @since 6.4.0
     974 *
     975 * @see serialize_block()
     976 *
     977 * @param array    $block    A representative array of a single parsed block object. See WP_Block_Parser_Block.
     978 * @param callable $callback Callback to run on each block in the tree before serialization.
     979 *                           It is called with the following arguments: $block, $parent_block, $block_index, $chunk_index.
     980 * @return string String of rendered HTML.
     981 */
     982function traverse_and_serialize_block( $block, $callback ) {
     983    $block_content = '';
     984    $block_index   = 0;
     985
     986    foreach ( $block['innerContent'] as $chunk_index => $chunk ) {
     987        if ( is_string( $chunk ) ) {
     988            $block_content .= $chunk;
     989        } else {
     990            $inner_block = call_user_func(
     991                $callback,
     992                $block['innerBlocks'][ $block_index ],
     993                $block,
     994                $block_index,
     995                $chunk_index
     996            );
     997            $block_index++;
     998            $block_content .= traverse_and_serialize_block( $inner_block, $callback );
     999        }
     1000    }
     1001
     1002    if ( ! is_array( $block['attrs'] ) ) {
     1003        $block['attrs'] = array();
     1004    }
     1005
     1006    return get_comment_delimited_block_content(
     1007        $block['blockName'],
     1008        $block['attrs'],
     1009        $block_content
     1010    );
     1011}
     1012
     1013/**
     1014 * Traverses the blocks applying transformations using the callback provided,
     1015 * and returns a joined string of the aggregate serialization of the given parsed blocks.
     1016 *
     1017 * This should be used when there is a need to modify the saved blocks.
     1018 * Prefer `serialize_blocks` when preparing blocks to be saved to post content.
     1019 *
     1020 * @since 6.4.0
     1021 *
     1022 * @see serialize_blocks()
     1023 *
     1024 * @param array[]  $blocks   An array of representative arrays of parsed block objects. See serialize_block().
     1025 * @param callable $callback Callback to run on each block in the tree before serialization.
     1026 *                           It is called with the following arguments: $block, $parent_block, $block_index, $chunk_index.
     1027 * @return string String of rendered HTML.
     1028 */
     1029function traverse_and_serialize_blocks( $blocks, $callback ) {
    9711030    $result = '';
    9721031    foreach ( $blocks as $block ) {
    973         $result .= serialize_block( $block, $callback );
     1032        // At the top level, there is no parent block, block index, or chunk index to pass to the callback.
     1033        $block = call_user_func( $callback, $block );
     1034        $result .= traverse_and_serialize_block( $block, $callback );
    9741035    }
    9751036    return $result;
  • trunk/tests/phpunit/tests/blocks/serialize.php

    r56557 r56620  
    1414    /**
    1515     * @dataProvider data_serialize_identity_from_parsed
     16     *
     17     * @param string $original Original block markup.
    1618     */
    1719    public function test_serialize_identity_from_parsed( $original ) {
    1820        $blocks = parse_blocks( $original );
    1921
    20         $actual   = serialize_blocks( $blocks );
    21         $expected = $original;
     22        $actual = serialize_blocks( $blocks );
    2223
    23         $this->assertSame( $expected, $actual );
     24        $this->assertSame( $original, $actual );
    2425    }
    2526
     
    5960     * @ticket 59327
    6061     *
    61      * @covers ::serialize_blocks
     62     * @covers ::traverse_and_serialize_blocks
    6263     */
    63     public function test_callback_argument() {
     64    public function test_traverse_and_serialize_blocks() {
    6465        $markup = "<!-- wp:outer --><!-- wp:inner {\"key\":\"value\"} -->Example.<!-- /wp:inner -->\n\nExample.\n\n<!-- wp:void /--><!-- /wp:outer -->";
    6566        $blocks = parse_blocks( $markup );
    6667
    67         $actual = serialize_blocks( $blocks, array( __CLASS__, 'add_attribute_to_inner_block' ) );
     68        $actual = traverse_and_serialize_blocks( $blocks, array( __CLASS__, 'add_attribute_to_inner_block' ) );
    6869
    6970        $this->assertSame(
     
    7980        return $block;
    8081    }
     82
     83    /**
     84     * @ticket 59327
     85     *
     86     * @covers ::traverse_and_serialize_blocks
     87     *
     88     * @dataProvider data_serialize_identity_from_parsed
     89     *
     90     * @param string $original Original block markup.
     91     */
     92    public function test_traverse_and_serialize_identity_from_parsed( $original ) {
     93        $blocks = parse_blocks( $original );
     94
     95        $actual = traverse_and_serialize_blocks(
     96            $blocks,
     97            function ( $block ) {
     98                return $block;
     99            }
     100        );
     101
     102        $this->assertSame( $original, $actual );
     103    }
    81104}
Note: See TracChangeset for help on using the changeset viewer.