Title: traverse_and_serialize_blocks
Published: November 8, 2023
Last modified: May 20, 2026

---

# traverse_and_serialize_blocks( array[] $blocks, callable $pre_callback = null, callable $post_callback = null ): string

## In this article

 * [Description](https://developer.wordpress.org/reference/functions/traverse_and_serialize_blocks/?output_format=md#description)
    - [See also](https://developer.wordpress.org/reference/functions/traverse_and_serialize_blocks/?output_format=md#see-also)
 * [Parameters](https://developer.wordpress.org/reference/functions/traverse_and_serialize_blocks/?output_format=md#parameters)
 * [Return](https://developer.wordpress.org/reference/functions/traverse_and_serialize_blocks/?output_format=md#return)
 * [Source](https://developer.wordpress.org/reference/functions/traverse_and_serialize_blocks/?output_format=md#source)
 * [Related](https://developer.wordpress.org/reference/functions/traverse_and_serialize_blocks/?output_format=md#related)
 * [Changelog](https://developer.wordpress.org/reference/functions/traverse_and_serialize_blocks/?output_format=md#changelog)

[ Back to top](https://developer.wordpress.org/reference/functions/traverse_and_serialize_blocks/?output_format=md#wp--skip-link--target)

This function’s access is marked private. This means it is not intended for use 
by plugin or theme developers, only by core. It is listed here for completeness.

Given an array of parsed block trees, applies callbacks before and after serializing
them and returns their concatenated output.

## 󠀁[Description](https://developer.wordpress.org/reference/functions/traverse_and_serialize_blocks/?output_format=md#description)󠁿

Recursively traverses the blocks and their inner blocks and applies the two callbacks
provided as arguments, the first one before serializing a block, and the second 
one after serializing.
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 blocks, or
to inject markup into the return value. Prefer `serialize_blocks` when preparing
blocks to be saved to post content.

This function is meant for internal use only.

### 󠀁[See also](https://developer.wordpress.org/reference/functions/traverse_and_serialize_blocks/?output_format=md#see-also)󠁿

 * [serialize_blocks()](https://developer.wordpress.org/reference/functions/serialize_blocks/)

## 󠀁[Parameters](https://developer.wordpress.org/reference/functions/traverse_and_serialize_blocks/?output_format=md#parameters)󠁿

 `$blocks`array[]required

An array of parsed blocks. See [WP_Block_Parser_Block](https://developer.wordpress.org/reference/classes/wp_block_parser_block/).

`$pre_callback`callableoptional

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.

Default:`null`

`$post_callback`callableoptional

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.

Default:`null`

## 󠀁[Return](https://developer.wordpress.org/reference/functions/traverse_and_serialize_blocks/?output_format=md#return)󠁿

 string Serialized block markup.

## 󠀁[Source](https://developer.wordpress.org/reference/functions/traverse_and_serialize_blocks/?output_format=md#source)󠁿

    ```php
    function traverse_and_serialize_blocks( $blocks, $pre_callback = null, $post_callback = null ) {
    	$result       = '';
    	$parent_block = null; // At the top level, there is no parent block to pass to the callbacks; yet the callbacks expect a reference.

    	$pre_callback_is_callable  = is_callable( $pre_callback );
    	$post_callback_is_callable = is_callable( $post_callback );

    	foreach ( $blocks as $index => $block ) {
    		if ( $pre_callback_is_callable ) {
    			$prev = 0 === $index
    				? null
    				: $blocks[ $index - 1 ];

    			$result .= call_user_func_array(
    				$pre_callback,
    				array( &$block, &$parent_block, $prev )
    			);
    		}

    		if ( $post_callback_is_callable ) {
    			$next = count( $blocks ) - 1 === $index
    				? null
    				: $blocks[ $index + 1 ];

    			$post_markup = call_user_func_array(
    				$post_callback,
    				array( &$block, &$parent_block, $next )
    			);
    		}

    		$result .= traverse_and_serialize_block( $block, $pre_callback, $post_callback );
    		$result .= $post_markup ?? '';
    	}

    	return $result;
    }
    ```

[View all references](https://developer.wordpress.org/reference/files/wp-includes/blocks.php/)
[View on Trac](https://core.trac.wordpress.org/browser/tags/7.0/src/wp-includes/blocks.php#L2010)
[View on GitHub](https://github.com/WordPress/wordpress-develop/blob/7.0/src/wp-includes/blocks.php#L2010-L2045)

## 󠀁[Related](https://developer.wordpress.org/reference/functions/traverse_and_serialize_blocks/?output_format=md#related)󠁿

| Uses | Description | 
| [traverse_and_serialize_block()](https://developer.wordpress.org/reference/functions/traverse_and_serialize_block/)`wp-includes/blocks.php` |

Traverses a parsed block tree and applies callbacks before and after serializing it.

  |

| Used by | Description | 
| [apply_block_hooks_to_content()](https://developer.wordpress.org/reference/functions/apply_block_hooks_to_content/)`wp-includes/blocks.php` |

Runs the hooked blocks algorithm on the given content.

  | 
| [wp_generate_block_templates_export_file()](https://developer.wordpress.org/reference/functions/wp_generate_block_templates_export_file/)`wp-includes/block-template-utils.php` |

Creates an export of the current templates and template parts from the site editor at the specified path in a ZIP file.

  |

## 󠀁[Changelog](https://developer.wordpress.org/reference/functions/traverse_and_serialize_blocks/?output_format=md#changelog)󠁿

| Version | Description | 
| [6.4.0](https://developer.wordpress.org/reference/since/6.4.0/) | Introduced. |

## User Contributed Notes

You must [log in](https://login.wordpress.org/?redirect_to=https%3A%2F%2Fdeveloper.wordpress.org%2Freference%2Ffunctions%2Ftraverse_and_serialize_blocks%2F)
before being able to contribute a note or feedback.