Make WordPress Core

Changeset 56620


Ignore:
Timestamp:
09/19/2023 12:48:41 PM (3 years 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.