Get specific Blocks from Post

The question:

I’m trying to load individual Post Blocks (by type) into separate divs, I’ve tried filtering tags but the outcome is there’s a bunch of abandoned divs and it’s overall messy and unpredictable.

I was wondering whether there is a way to retrieve e.g. only Paragraph Blocks from a Post?

The Solutions:

Below are the methods you can try. The first solution is probably the best. Try others if the first one doesn’t work. Senior developers aren’t just copying/pasting – they read the methods carefully & apply them wisely to each case.

Method 1

PHP-side you can pass the post_content to the parse_blocks() function which will provide you with an array of associative arrays representing each block. Similar functionality is offered JS-side in the form of the wp.blocks.parse() function from the @wordpress/blocks package. For illustrative purposes, here is a var_dump() of that output for the default “Sample Page”:

array(9) {
  [0] => array(5) {
    'blockName' => string(14) "core/paragraph"
    'attrs' => array(0) {}
    'innerBlocks' => array(0) {}
    'innerHTML' => string(278) "
<p>This is an example page. It's different from a blog post because it will stay in one place and will show up in your site navigation (in most themes). Most people start with an About page that introduces them to potential site visitors. It might say something like this:</p>"
    'innerContent' => array(1) {
      [0] => string(278) "
<p>This is an example page. It's different from a blog post because it will stay in one place and will show up in your site navigation (in most themes). Most people start with an About page that introduces them to potential site visitors. It might say something like this:</p>"
    }
  }
  [1] => array(5) {
    'blockName' => NULL
    'attrs' => array(0) {}
    'innerBlocks' => array(0) {}
    'innerHTML' => string(2) "

"
    'innerContent' => array(1) {
      [0] => string(2) "

"
    }
  }
  [2] => array(5) {
    'blockName' => string(10) "core/quote"
    'attrs' => array(0) {}
    'innerBlocks' => array(0) {}
    'innerHTML' => string(260) "
<blockquote class="wp-block-quote"><p>Hi there! I'm a bike messenger by day, aspiring actor by night, and this is my website. I live in Los Angeles, have a great dog named Jack, and I like piña coladas. (And gettin' caught in the rain.)</p></blockquote>"
    'innerContent' => array(1) {
      [0] => string(260) "
<blockquote class="wp-block-quote"><p>Hi there! I'm a bike messenger by day, aspiring actor by night, and this is my website. I live in Los Angeles, have a great dog named Jack, and I like piña coladas. (And gettin' caught in the rain.)</p></blockquote>"
    }
  }
  [3] => array(5) {
    'blockName' => NULL
    'attrs' => array(0) {}
    'innerBlocks' =>
    array(0) {}
    'innerHTML' => string(2) "

"
    'innerContent' => array(1) {
      [0] => string(2) "

"
    }
  }
  [4] => array(5) {
    'blockName' => string(14) "core/paragraph"
    'attrs' => array(0) {}
    'innerBlocks' => array(0) {}
    'innerHTML' => string(35) "<p>...or something like this:</p>"
    'innerContent' => array(1) {
      [0] => string(35) "<p>...or something like this:</p>"
    }
  }
  [5] => array(5) {
    'blockName' => NULL
    'attrs' => array(0) {}
    'innerBlocks' => array(0) {}
    'innerHTML' => string(2) "

"
    'innerContent' => array(1) {
      [0] => string(2) "

"
    }
  }
  [6] => array(5) {
    'blockName' => string(10) "core/quote"
    'attrs' => array(0) {}
    'innerBlocks' => array(0) {}
    'innerHTML' => string(288) "
<blockquote class="wp-block-quote"><p>The XYZ Doohickey Company was founded in 1971, and has been providing quality doohickeys to the public ever since. Located in Gotham City, XYZ employs over 2,000 people and does all kinds of awesome things for the Gotham community.</p></blockquote>"
    'innerContent' => array(1) {
      [0] => string(288) "
<blockquote class="wp-block-quote"><p>The XYZ Doohickey Company was founded in 1971, and has been providing quality doohickeys to the public ever since. Located in Gotham City, XYZ employs over 2,000 people and does all kinds of awesome things for the Gotham community.</p></blockquote>"
    }
  }
  [7] => array(5) {
    'blockName' => NULL
    'attrs' => array(0) {}
    'innerBlocks' => array(0) {}
    'innerHTML' => string(2) "

"
    'innerContent' => array(1) {
      [0] => string(2) "

"
    }
  }
  [8] => array(5) {
    'blockName' => string(14) "core/paragraph"
    'attrs' => array(0) {}
    'innerBlocks' => array(0) {}
    'innerHTML' => string(180) "
<p>As a new WordPress user, you should go to <a href="http://localhost:8888/wp-admin/">your dashboard</a> to delete this page and create new pages for your content. Have fun!</p>"
    'innerContent' => array(1) {
      [0] => string(180) "
<p>As a new WordPress user, you should go to <a href="http://localhost:8888/wp-admin/">your dashboard</a> to delete this page and create new pages for your content. Have fun!</p>"
    }
  }
}

When parsing this array for a certain block-type like core/paragraph, it should be noted that you should traverse each blocks’ innerBlocks array as well in order to address nested blocks, such as those in columns or groups:

/**
 * Processes a block list output from the parse_blocks() function
 * and returns a flat list of block arrays matching the specified
 * type.
 * 
 * @param array  $blocks Output from parse_blocks().
 * @param string $type The block type handle to search for.
 * @return array An array of all block arrays with the specified type.
 **/
function wpse390419_find_blocks( $blocks, $type ) {
  $matches = [];

  foreach( $blocks as $block ) {
    if( $block['blockName'] === $type )
      $matches[] = $block;

    if( count( $block['innerBlocks'] ) ) {
      $matches = array_merge(
        $matches,
        wpse390419_find_blocks( $block['innerBlocks'], $type )
      );
    }
  }

  return $matches;
}
$paragraph_blocks = wpse390419_find_blocks(
  parse_blocks( get_the_content() ),
  'core/paragraph'
);

However, if you are attempting to parse blocks out of the content in order to display them in specific locations, you are somewhat undermining one of the Block Editor’s greatest strengths, that being it’s WYSIWYG interface. A better solution would be to implement a Block Pattern or Block Template in order to restrict the placement of blocks.


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Comment