Title: serialize_blocks
Published: April 1, 2020
Last modified: February 24, 2026

---

# serialize_blocks( array[] $blocks ): string

## In this article

 * [Parameters](https://developer.wordpress.org/reference/functions/serialize_blocks/?output_format=md#parameters)
 * [Return](https://developer.wordpress.org/reference/functions/serialize_blocks/?output_format=md#return)
 * [Source](https://developer.wordpress.org/reference/functions/serialize_blocks/?output_format=md#source)
 * [Related](https://developer.wordpress.org/reference/functions/serialize_blocks/?output_format=md#related)
 * [Changelog](https://developer.wordpress.org/reference/functions/serialize_blocks/?output_format=md#changelog)
 * [User Contributed Notes](https://developer.wordpress.org/reference/functions/serialize_blocks/?output_format=md#user-contributed-notes)

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

Returns a joined string of the aggregate serialization of the given parsed blocks.

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

 `$blocks`array[]required

Array of block structures.

 * `...$0` array
 *  An associative array of a single parsed block object. See [WP_Block_Parser_Block](https://developer.wordpress.org/reference/classes/wp_block_parser_block/).
    - `blockName` string|null
    - Name of block.
    - `attrs` array
    - Attributes from block comment delimiters.
    - `innerBlocks` array[]
    - List of inner blocks. An array of arrays that have the same structure as this
      one.
    - `innerHTML` string
    - HTML from inside block comment delimiters.
    - `innerContent` array
    - List of string fragments and null markers where inner blocks were found.

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

 string String of rendered HTML.

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

    ```php
    function serialize_blocks( $blocks ) {
    	return implode( '', array_map( 'serialize_block', $blocks ) );
    }
    ```

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

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

| Used by | Description | 
| [WP_Classic_To_Block_Menu_Converter::convert()](https://developer.wordpress.org/reference/classes/wp_classic_to_block_menu_converter/convert/)`wp-includes/class-wp-classic-to-block-menu-converter.php` |

Converts a Classic Menu to blocks.

  | 
| [WP_REST_Block_Patterns_Controller::prepare_item_for_response()](https://developer.wordpress.org/reference/classes/wp_rest_block_patterns_controller/prepare_item_for_response/)`wp-includes/rest-api/endpoints/class-wp-rest-block-patterns-controller.php` |

Prepare a raw block pattern before it gets output in a REST API response.

  | 
| [WP_REST_Templates_Controller::prepare_item_for_response()](https://developer.wordpress.org/reference/classes/wp_rest_templates_controller/prepare_item_for_response/)`wp-includes/rest-api/endpoints/class-wp-rest-templates-controller.php` |

Prepare a single template output for response

  |

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

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

## 󠀁[User Contributed Notes](https://developer.wordpress.org/reference/functions/serialize_blocks/?output_format=md#user-contributed-notes)󠁿

 1.   [Skip to note 2 content](https://developer.wordpress.org/reference/functions/serialize_blocks/?output_format=md#comment-content-4974)
 2.    [si3ard](https://profiles.wordpress.org/si3ard/)  [  5 years ago  ](https://developer.wordpress.org/reference/functions/serialize_blocks/#comment-4974)
 3.  [You must log in to vote on the helpfulness of this note](https://login.wordpress.org?redirect_to=https%3A%2F%2Fdeveloper.wordpress.org%2Freference%2Ffunctions%2Fserialize_blocks%2F%23comment-4974)
     Vote results for this note: 3[You must log in to vote on the helpfulness of this note](https://login.wordpress.org?redirect_to=https%3A%2F%2Fdeveloper.wordpress.org%2Freference%2Ffunctions%2Fserialize_blocks%2F%23comment-4974)
 4.  **Used with `wp_update_post()`**
 5.  Sample of how to use `serialize_blocks()` after making adjustments to a post’s
     block content.
 6.  In this use case, I wanted to create a cross-reference between the captions used
     on media in a gallery, and the captions saved to the media’s corresponding Attachment
     post. These can easily get out of date if a user is only managing them in one 
     place or the other.
 7.      ```php
         class WPDocs_Gallery_Caption_Demo {
     
         	// Property used for storing attachment captions
         	// that need to be added to gallery block content
         	private $_missingBlockCaptions;
     
         	function __construct() {
     
         		add_action( 'save_post', array( $this, 'filterGalleries' ), 10, 2 );
     
         	}
     
         	public function filterGalleries( $post_id, $post ) {
     
         		// Reset this property on each save.
         		$this->_missingBlockCaptions = [];
     
         		// Fetch parsed blocks from the post's saved content
         		$blocks = parse_blocks( $post->post_content );
     
         		// Check for missing captions if a Gallery Block is used on the page.
         		// Also pass along the index of the block for use in editing content later
         		foreach ( $blocks as $i => $block ) {
     
         			if ( 'core/gallery' === $block['blockName'] ) {
     
         				$this->_checkCaptions( $post, $block, $i );
     
         			}
     
         		}
     
         	}
     
         	private function _checkCaptions( $post, $block, $blockIndex ) {
     
         		foreach ( $block['attrs']['ids'] as $attachmentID ) {
     
         			$pattern        = sprintf( '/wp-image-%s"/><figcaption[^>]+>(?<caption>[^<]+)</figcaption/', $attachmentID );
         			$savedCaption   = wp_get_attachment_caption( $attachmentID );
         			$galleryCaption = preg_match_all( $pattern, $block['innerHTML'], $matches );
     
         			// First check if the Gallery has a caption but the Attachment doesn't,
         			// then check if the Attachent has a caption but the Gallery doesn't.
         			if ( empty( $savedCaption ) && $galleryCaption ) {
     
         				// Immediately update the attachment's missing caption.
         				$this->_updateAttachmentCaption( $attachmentID, $matches['caption'][0] );
     
         			} elseif ( ! empty( $savedCaption ) && ! $galleryCaption ) {
     
         				// Store the block index, attachment ID and caption
         				// for use later when we bulk-update the post content.
         				$this->_missingBlockCaptions[ $blockIndex ][ $attachmentID ] = $savedCaption;
     
         			}
     
         		}
     
         		// Use a bulk method to update multiple missing captions in the post content
         		// for the Attachments that have a caption in their `post_excerpt` value,
         		// since this is one `post_content` value for multiple media attachments.
         		if ( ! empty( $this->_missingBlockCaptions ) ) {
         			$this->_addBlockCaptions( $post );
         		}
     
         	}
     
         	private function _updateAttachmentCaption( $attachmentID, $caption ) {
     
         		wp_update_post( array(
         			'ID'            => $attachmentID,
         			'post_excerpt'  => $caption
         		) );
     
         	}
     
         	private function _addBlockCaptions( $post ) {
     
         		// Parse out the blocks so we can update the `innerContent`
         		// for the corresponding indices stored $missingBlockCaptions.
         		$blocks = parse_blocks( $post->post_content );
     
         		foreach ( $this->_missingBlockCaptions as $blockIndex => $missingCaptions ) {
     
         			foreach ( $misingCaptions as $attachmentID => $caption ) {
     
         				// Match the end of the target img tag using its saved ID.
         				$pattern = sprintf( '/(wp-image-%s"/>)/', $attachmentID );
     
         				// Add the missing figcaption markup, using the saved caption
         				// from the Attachment's `post_excerpt` value we got in $this->checkCaptions()
         				$replace = sprintf( '$1<figcaption class="blocks-gallery-item__caption">%s</figcaption>', $caption );
     
         				// Insert our new figcaption markup into the target block
         				// using the $blockIndex reference.
         				$blocks[ $blockIndex ]['innerContent'][0] = preg_replace( $pattern, $replace, $blocks[ $blockIndex ]['innerContent'][0] );
     
         			}
     
         		}
     
         		// Using `serialize_blocks` will handle `serialize_block`
         		// for each block in $blocks.
         		$content = serialize_blocks( $blocks );
         		$updatedPost = array(
         			'ID'            => $post->ID,
         			'post_content'  => $content
         		);
     
         		// Update the post with the new adjustments made to the gallery blocks' `innerContent`
         		wp_update_post( $updatedPost );
     
         	}
     
         }
     
         new WPDocs_Gallery_Caption_Demo();
         ```
     
 8.  Gallery blocks have a caption field on the block editor view that is static to
     the block and does not save back to the original Attachment. This class updates
     the Attachment’s caption if it is empty while a static one was written in the 
     a gallery block. It also does the converse; it adds a  tag with the Attachment’s
     caption value to the gallery items that don’t have a static caption written on
     them.
 9.  The functional use for this is to update the captions into the database so that
     the user will see them on page reload, instead of trusting that they will show
     up only in the front end (using the `render_block` filter).
 10.  [Log in to add feedback](https://login.wordpress.org/?redirect_to=https%3A%2F%2Fdeveloper.wordpress.org%2Freference%2Ffunctions%2Fserialize_blocks%2F%3Freplytocom%3D4974%23feedback-editor-4974)

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