Skip to content

Commit 44e71c8

Browse files
committed
General: Add optional callback argument to serialize_block(s).
Allow passing a function callback to serialize_block(s) that is invoked on each node in the tree of parsed blocks as it is traversed for serialization. A function argument was chosen for passing the callback function as it reflects a pattern familiar from other algorithms that apply a given callback function while traversing a data structure -- most notably PHP's own `array_map()`. Introducing a filter was considered as an alternative but ultimately dismissed. For a fairly low-level and general-purpose function such as `serialize_block()`, using a filter to pass the callback seemed risky, as it also requires ''removing'' that filter after usage in order to prevent the callback from being accidentally applied when `serialize_block()` is called in an entirely different context. Introducing a separate function for applying a given operation during tree traversal (i.e. independently of serialization) was also considered but dismissed, as it would unnecessarily duplicate tree traversal. Props dlh, gziolo. Fixes #59327. See #59313. git-svn-id: https://develop.svn.wordpress.org/trunk@56557 602fd350-edb4-49c9-b593-d223f7449a82
1 parent cc775b9 commit 44e71c8

File tree

2 files changed

+42
-6
lines changed

2 files changed

+42
-6
lines changed

src/wp-includes/blocks.php

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -794,16 +794,22 @@ function get_comment_delimited_block_content( $block_name, $block_attributes, $b
794794
* instead preserve the markup as parsed.
795795
*
796796
* @since 5.3.1
797+
* @since 6.4.0 The `$callback` parameter was added.
797798
*
798-
* @param array $block A representative array of a single parsed block object. See WP_Block_Parser_Block.
799+
* @param array $block A representative array of a single parsed block object. See WP_Block_Parser_Block.
800+
* @param callable|null $callback Optional. Callback to run on each block in the tree before serialization. Default null.
799801
* @return string String of rendered HTML.
800802
*/
801-
function serialize_block( $block ) {
803+
function serialize_block( $block, $callback = null ) {
804+
if ( is_callable( $callback ) ) {
805+
$block = call_user_func( $callback, $block );
806+
}
807+
802808
$block_content = '';
803809

804810
$index = 0;
805811
foreach ( $block['innerContent'] as $chunk ) {
806-
$block_content .= is_string( $chunk ) ? $chunk : serialize_block( $block['innerBlocks'][ $index++ ] );
812+
$block_content .= is_string( $chunk ) ? $chunk : serialize_block( $block['innerBlocks'][ $index++ ], $callback );
807813
}
808814

809815
if ( ! is_array( $block['attrs'] ) ) {
@@ -822,12 +828,18 @@ function serialize_block( $block ) {
822828
* parsed blocks.
823829
*
824830
* @since 5.3.1
831+
* @since 6.4.0 The `$callback` parameter was added.
825832
*
826-
* @param array[] $blocks An array of representative arrays of parsed block objects. See serialize_block().
833+
* @param array[] $blocks An array of representative arrays of parsed block objects. See serialize_block().
834+
* @param callable|null $callback Optional. Callback to run on each block in the tree before serialization. Default null.
827835
* @return string String of rendered HTML.
828836
*/
829-
function serialize_blocks( $blocks ) {
830-
return implode( '', array_map( 'serialize_block', $blocks ) );
837+
function serialize_blocks( $blocks, $callback = null ) {
838+
$result = '';
839+
foreach ( $blocks as $block ) {
840+
$result .= serialize_block( $block, $callback );
841+
};
842+
return $result;
831843
}
832844

833845
/**

tests/phpunit/tests/blocks/serialize.php

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,4 +54,28 @@ public function test_serialized_block_name() {
5454
$this->assertSame( 'example', strip_core_block_namespace( 'core/example' ) );
5555
$this->assertSame( 'plugin/example', strip_core_block_namespace( 'plugin/example' ) );
5656
}
57+
58+
/**
59+
* @ticket 59327
60+
*
61+
* @covers ::serialize_blocks
62+
*/
63+
public function test_callback_argument() {
64+
$markup = "<!-- wp:outer --><!-- wp:inner {\"key\":\"value\"} -->Example.<!-- /wp:inner -->\n\nExample.\n\n<!-- wp:void /--><!-- /wp:outer -->";
65+
$blocks = parse_blocks( $markup );
66+
67+
$actual = serialize_blocks( $blocks, array( __CLASS__, 'add_attribute_to_inner_block' ) );
68+
69+
$this->assertSame(
70+
"<!-- wp:outer --><!-- wp:inner {\"key\":\"value\",\"myattr\":\"myvalue\"} -->Example.<!-- /wp:inner -->\n\nExample.\n\n<!-- wp:void /--><!-- /wp:outer -->",
71+
$actual
72+
);
73+
}
74+
75+
public static function add_attribute_to_inner_block( $block ) {
76+
if ( 'core/inner' === $block['blockName'] ) {
77+
$block['attrs']['myattr'] = 'myvalue';
78+
}
79+
return $block;
80+
}
5781
}

0 commit comments

Comments
 (0)