traverse_and_serialize_block

The timeline below displays how wordpress function traverse_and_serialize_block has changed across different WordPress versions. If a version is not listed, refer to the next available version below.

WordPress Version: 6.4

/**
 * Traverses a parsed block tree and applies callbacks before and after serializing it.
 *
 * Recursively traverses the block and its inner blocks and applies the two callbacks provided as
 * arguments, the first one before serializing the block, and the second one after serializing it.
 * If either callback returns a string value, it will be prepended and appended to the serialized
 * block markup, respectively.
 *
 * The callbacks will receive a reference to the current block as their first argument, so that they
 * can also modify it, and the current block's parent block as second argument. Finally, the
 * `$pre_callback` receives the previous block, whereas the `$post_callback` receives
 * the next block as third argument.
 *
 * Serialized blocks are returned including comment delimiters, and with all attributes serialized.
 *
 * This function should be used when there is a need to modify the saved block, or to inject markup
 * into the return value. Prefer `serialize_block` when preparing a block to be saved to post content.
 *
 * This function is meant for internal use only.
 *
 * @since 6.4.0
 * @access private
 *
 * @see serialize_block()
 *
 * @param array    $block         A representative array of a single parsed block object. See WP_Block_Parser_Block.
 * @param callable $pre_callback  Callback to run on each block in the tree before it is traversed and serialized.
 *                                It is called with the following arguments: &$block, $parent_block, $previous_block.
 *                                Its string return value will be prepended to the serialized block markup.
 * @param callable $post_callback Callback to run on each block in the tree after it is traversed and serialized.
 *                                It is called with the following arguments: &$block, $parent_block, $next_block.
 *                                Its string return value will be appended to the serialized block markup.
 * @return string Serialized block markup.
 */
function traverse_and_serialize_block($block, $pre_callback = null, $post_callback = null)
{
    $block_content = '';
    $block_index = 0;
    foreach ($block['innerContent'] as $chunk) {
        if (is_string($chunk)) {
            $block_content .= $chunk;
        } else {
            $inner_block = $block['innerBlocks'][$block_index];
            if (is_callable($pre_callback)) {
                $prev = (0 === $block_index) ? null : $block['innerBlocks'][$block_index - 1];
                $block_content .= call_user_func_array($pre_callback, array(&$inner_block, &$block, $prev));
            }
            if (is_callable($post_callback)) {
                $next = (count($block['innerBlocks']) - 1 === $block_index) ? null : $block['innerBlocks'][$block_index + 1];
                $post_markup = call_user_func_array($post_callback, array(&$inner_block, &$block, $next));
            }
            $block_content .= traverse_and_serialize_block($inner_block, $pre_callback, $post_callback);
            $block_content .= isset($post_markup) ? $post_markup : '';
            ++$block_index;
        }
    }
    if (!is_array($block['attrs'])) {
        $block['attrs'] = array();
    }
    return get_comment_delimited_block_content($block['blockName'], $block['attrs'], $block_content);
}