Can You Access ACF Block Data from a Different Page?
Occasionally, you may find yourself wanting to display data from a block’s custom field on a completely different page from the one the block was added to. With standard custom fields, because each bit of data is stored separately in the database, it’s much easier to target that specific bit of data and display it anywhere. ACF provides a route to do just that through their the_field function.
By simply including the post ID of the item when calling this function, you can grab a particular field from the specified page. If you wanted to display the content of an ACF field named custom_field that is attached to a post with an ID of 12, you could do that like:
<?php the_field('custom_field',12); ?>
However, if you’re working with ACF blocks, you can’t pull a block ACF field’s value using this same approach. All data from ACF blocks is stored in the post content field so, while you can grab the entire post content field with an ID, understandably that doesn’t work well if you’re just wanting one bit of data from within it. So we need a route to identify specific pieces of data from the larger overall post_content field. This is possible leveraging a function called parse_blocks.
What is the parse_blocks WordPress function?
The parse_blocks function works with the post content field of a Gutenberg page to turn one collective chunk of various blocks of a post or page and return that data as an array of individual block objects. This is key to being able to target a specific bit of data in a specific block.
Just like when accessing traditional post meta from other locations, it’s important to know the ID of wherever you’re trying to pull content from. Instead of doing it with a the_field call including that ID, instead you’re going to grab the post_content field for that ID to use with parse_blocks. Just like with the above example, if the ID of the item you’re trying to pull data from is 12, you would want to grab the post_content field from it using something like get_post_field.
<?php // replace 12 with your item ID $postContent = get_post_field('post_content', 12); // $blocks would contain an array of individual blocks on this page $blocks = parse_blocks($postContent); ?>
Once you’ve used parse_blocks to create an array of block objects, a great first step when you’re getting your feet wet with this function is to just loop through the blocks variable with a foreach function and var_dump the individual block to see what you’re working with. (Note: You should not use var_dump on a production URL as it will spit out an array of data. It’s purely a debugging function that gives a good view of any variable’s structure.)
<?php // replace 12 with your item ID $postContent = get_post_field('post_content', 12); // $blocks would contain an array of individual blocks on this page $blocks = parse_blocks($postContent); // loop through blocks and spit out each block individually foreach($blocks as $block) { var_dump($block); } ?>
When dumping out the value of each block, you’ll see each block is an array of data and it has things like name, attributes, innerBlocks, innerHTML and similar. ACF data should be found in the attributes (attrs) array of the block, within the nested data array. So if you had an ACF field called custom_field in a block, you would reach it with $block[‘attrs’][‘data’][‘custom_field’].
Now, odds are that the block you are grabbing data from isn’t the only block on the page so there’s no sense in hitting a bunch of other blocks looking for data from one block. So let’s add a statement first checking to see if the block is the ACF block you want and if not, move along to the next block.
You can check to see if it’s a specific block by looking at the block name. ACF block names are acf/[block-name] so if I created an ACF block called Sample Block, the block name I’m looking for would be acf/sample-block.
<?php // replace 12 with your item ID $postContent = get_post_field('post_content', 12); // $blocks would contain an array of individual blocks on this page $blocks = parse_blocks($postContent); // loop through the $blocks variable foreach($blocks as $block) { // replace acf/sample-block with your block name if( 'acf/sample-block' !== $block['blockName'] ) { continue; } // the below only applies to the specified block above $dataIWant = $block['attrs']['data']['custom_field']; } // this would display that data echo $dataIWant; ?>
Depending on the ACF field type you’re using with a Gutenberg block or if you start getting into InnerBlocks and similar, getting data elsewhere gets increasingly complex, but this should give some insight on how you could leverage parse_blocks to pull in ACF Gutenberg block data on locations different from where the block is actually used. It’s not the most performant so it should be used sparingly, but it does get the job done.
Using parse_blocks with ACF can be extremely powerful and I’ll dive into more things you can do pairing the two together in the future!