---
description: https://www.billerickson.net/access-gutenberg-block-data/
---

# Access block data with PHP using parse\_blocks() and render\_block  (ok)

## Access block data with PHP using parse\_blocks() and render\_block()

![](https://2370029328-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LWPtKFbhw0XehxVuoiZ%2F-MkLv8YNBzjj7ovu2XG1%2F-MkLvO1eXsM2tX7kirE3%2FScreenshot_7.png?alt=media\&token=635a124e-397a-4bff-8980-8d269b29b324)

```
<!-- wp:acf/program-detail-header {
    "id": "block_6126c0a595587",
    "name": "acf\/program-detail-header",
    "data": {
        "image": 2624,
        "_image": "field_612622916c3d8",
        "overview": 1093,
        "_overview": "field_612622986c3d9",
        "photo_credit": "zpouiuiui",
        "_photo_credit": "field_612776c737c70",
        "photo_link": "example.com",
        "_photo_link": "field_612776d537c71"
    },
    "align": "",
    "mode": "preview"
} /-->

<!-- wp:paragraph -->
<p>aaaaaaaaaaaaa 1</p>
<!-- /wp:paragraph -->
```

![](https://2370029328-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LWPtKFbhw0XehxVuoiZ%2F-MkLuV1Q8_0hVzELr97w%2F-MkLud99l2ddXXsQBfJU%2FScreenshot_6.png?alt=media\&token=261399db-843f-4134-ade7-d9cd6b1b92d4)

Sử dụng code&#x20;

```
global $post;
$blocks = parse_blocks( $post->post_content );
echo "<pre>";
var_export($blocks);
echo "</pre>";
```

Kết quả:

![](https://2370029328-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LWPtKFbhw0XehxVuoiZ%2F-MkLv8YNBzjj7ovu2XG1%2F-MkLviHw8b5TeGVyXqUZ%2FScreenshot_8.png?alt=media\&token=54273d16-74c6-408d-9d3c-82ef0d98eb3f)



## Access block data with PHP using parse\_blocks() and render\_block()

written byBill Ericksonpublished onMay 30, 2019discussed by[37 Comments](https://www.billerickson.net/access-gutenberg-block-data/#comments)

![](https://www.billerickson.net/wp-content/uploads/2019/05/access-block-data.jpg)

The Gutenberg block editor organizes your content into discrete blocks, and WordPress includes functions for easily accessing the individual blocks within a post.

Here’s a quick summary of how the functions work, and examples of them in use.

**Jump to Section:**

1. [parse\_blocks()](https://www.billerickson.net/access-gutenberg-block-data/#parse-blocks)
2. [render\_block()](https://www.billerickson.net/access-gutenberg-block-data/#render-block)
3. [Display blockquote from post](https://www.billerickson.net/access-gutenberg-block-data/#blockquote-from-post)
4. [Table of contents from headings](https://www.billerickson.net/access-gutenberg-block-data/#table-of-contents-from-headings)
5. [ACF block data](https://www.billerickson.net/access-gutenberg-block-data/#acf-block-data)

### parse\_blocks() <a href="#parse-blocks" id="parse-blocks"></a>

This function converts the HTML comments and markup stored in `post_content` into an array of parsed block objects.

**Usage**: `$blocks = parse_blocks( $post->post_content );`

The `post_content` of my [Style Guide](https://www.billerickson.net/style-guide/) looks like:

```
<!-- wp:paragraph {"fontSize":"large"} -->
<p class="has-large-font-size">Lorem <strong>ipsum</strong> dolor <em>sit amet</em>, consectetur <a class="map-link" href="https://maps.google.com/?q=Houston,+TX">adipiscing elit</a>, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":1} -->
<h1>Heading 1</h1>
<!-- /wp:heading -->
```

After running it through `parse_blocks()`, it looks like:

```
Array
(
    [0] => Array
        (
            [blockName] => core/paragraph
            [attrs] => Array
                (
                    [fontSize] => large
                )

            [innerBlocks] => Array
                (
                )

            [innerHTML] => 
<p class="has-large-font-size">Lorem <strong>ipsum</strong> dolor <em>sit amet</em>, consectetur <a class="map-link" href="https://maps.google.com/?q=Houston,+TX">adipiscing elit</a>, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>

            [innerContent] => Array
                (
                    [0] => 
<p class="has-large-font-size">Lorem <strong>ipsum</strong> dolor <em>sit amet</em>, consectetur <a class="map-link" href="https://maps.google.com/?q=Houston,+TX">adipiscing elit</a>, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>

                )

        )

    [1] => Array
        (
            [blockName] => 
            [attrs] => Array
                (
                )

            [innerBlocks] => Array
                (
                )

            [innerHTML] => 


            [innerContent] => Array
                (
                    [0] => 


                )

        )

    [2] => Array
        (
            [blockName] => core/heading
            [attrs] => Array
                (
                    [level] => 1
                )

            [innerBlocks] => Array
                (
                )

            [innerHTML] => 
<h1>Heading 1</h1>

            [innerContent] => Array
                (
                    [0] => 
<h1>Heading 1</h1>

                )
```

### render\_block() <a href="#render-block" id="render-block"></a>

This function takes a single parsed block object and returns the rendered HTML for that block.

**Usage:** `echo render_block( $block );`

_Note:_ While this function does convert the block object into the rendered HTML, it does not run all the additional filters that are typically applied to the content, like converting lines to paragraphs, rendering shortcodes, and rendering embeds.

In many cases, you’ll want to use the `the_content` filter to add these extras. Example: `echo apply_filters( 'the_content', render_block( $block ) );`

### Display blockquote from post <a href="#blockquote-from-post" id="blockquote-from-post"></a>

On [my portfolio archive page,](https://www.billerickson.net/projects/) every 4th project includes a blockquote. You could pull this directly from the content of the portfolio item by looping through the blocks and displaying the `core/quote` block, if one is found.

Add this function to your theme, then call `be_display_post_blockquote()` to display the quote.

```
/**
 * Display blockquote from post 
 * @link https://www.billerickson.net/access-gutenberg-block-data/
 */
function be_display_post_blockquote() {
  global $post;
  $blocks = parse_blocks( $post->post_content );
  foreach( $blocks as $block ) {
    if( 'core/quote' === $block['blockName'] ) {
      echo render_block( $block );
      break;
    }
  }
}
```

### Table of contents from headings <a href="#table-of-contents-from-headings" id="table-of-contents-from-headings"></a>

In [a previous tutorial](https://www.billerickson.net/building-gutenberg-block-acf/#table-of-contents-block) I showed how to dynamically build a table of contents by parsing the HTML.

Converting the HTML to blocks makes this much easier. You loop through the blocks and find the `core/heading` ones.

The example below makes a simple ordered list of all the headings in the page. You could take this a step further and use `$block['attrs']['level']` to make a nested list based on the heading level (ex: h3 is subordinate to h2).

```
/**
 * List post headings 
 * @link https://www.billerickson.net/access-gutenberg-block-data/
 */
function be_list_post_headings() {
	global $post;
	$blocks = parse_blocks( $post->post_content );
	$headings = array();
	foreach( $blocks as $block ) {
		if( 'core/heading' === $block['blockName'] )
			$headings[] = wp_strip_all_tags( $block['innerHTML'] );
	}
	if( !empty( $headings ) ) {
		echo '<ol class="table-of-contents">';
		foreach( $headings as $heading )
			echo '<li>' . $heading . '</li>';
		echo '</ol>';
	}
}
```

Unfortunately WordPress does not store the heading’s ID as an `anchor` attribute, so you’ll still need to manipulate the HTML if you want to create anchor links ([example](https://gist.github.com/billerickson/c451a7b2ef0c8ee4e48b7c17f536f39b#file-functions-php-L13-L15)).

### ACF block data <a href="#acf-block-data" id="acf-block-data"></a>

If you have [built a custom block with Advanced Custom Fields](https://www.billerickson.net/building-gutenberg-block-acf/), you can easily access all the block data using this method.

ACF generates dynamic blocks. Rather than storing actual HTML, it stores **all** of the block data in the HTML comments and then dynamically renders it using the PHP file or function you specify.

I’m working on a site that includes a “Service” block. It has fields for title, anchor link, content, and “success story” (a linked post from elsewhere).![](https://www.billerickson.net/wp-content/uploads/2019/05/acf-service-block.jpg)

The homepage includes links to the top-level pages, as well as anchor links to each individual service block. I’m using `parse_blocks()` to find all of the `acf/service` blocks, then building the links using the `$block['attrs']` data.![](https://www.billerickson.net/wp-content/uploads/2019/05/home-service-listing.jpg)

```
/**
 * Get service sections
 * @link https://www.billerickson.net/access-gutenberg-block-data/
 */
function ea_get_service_sections() {

	$sections = array();

	global $post;
	$blocks = parse_blocks( $post->post_content );
	foreach( $blocks as $block ) {
		if( 'acf/service' !== $block['blockName'] )
			continue;

		$title = $anchor = '';
		if( !empty( $block['attrs']['data']['title'] ) )
			$title = $block['attrs']['data']['title'];

		if( !empty( $block['attrs']['data']['anchor'] ) )
			$anchor = $block['attrs']['data']['anchor'];

		if( empty( $anchor ) )
			$anchor = $title;

		$sections[] = '<a href="' . get_permalink() . '#' . sanitize_title_with_dashes( $anchor ) . '">' . esc_html( $title ) . '</a>';
	}

	if( empty( $sections ) )
		return;

	echo '<ul class="service-sections">';
	foreach( $sections as $section )
		echo '<li>' . $section . '</li>';
	echo '</ul>';
}
```
