I have noticed a bug/quirk in how the ACF Post Object field type functions inside the render template for an ACF Gutenberg Block.
In short, after running setup_postdata()
on a Post Object, the_field()
and get_field()
do not work as expected.
Here is an example ACF Block render template that demonstrates the problem:
<?php
$post_object = get_field('my_post_object_field');
if( $post_object ):
global $post; // Need to make sure we overwrite the global Post Object
$post = $post_object; // override $post
// setup_postdata() works as expected. e.g. the_title() will display
// the title of the post referred to by $post_object.
setup_postdata($post);
// Normally, setup_postdata() is all that is required to let ACF
// know the new post ID, so that functions such as the_field() pull
// data from the correct post.
// However the_field('my_custom_field') is broken. It tries to pull
// 'my_custom_field' from the original global $post, when it should
// be pulling from the post referred to by $post_object.
the_field('my_custom_field');
// For the_field() to work correctly we have to explicitly pass it
// the ID of our Post Object:
the_field('my_custom_field', $post->ID);
endif;
?>
Please note that this quirk is specific to ACF’s Gutenberg Blocks. It does not affect ACF meta fields.
I assume that this is a scoping issue. My question: Is there a way to force ACF to recognise that it is supposed to be operating on the global $post
, instead of having to explicitly pass it a post ID every time?
Alternatively you can use
get_the_ID();
To pull the post id, which does work when the post is published, but will not actually pull the Post ID for the preview. I’d love to figure out why or what that work-around is though.
It seems that throughout the Gutenberg Blocks, the ID is changed to the Block ID instead of housing the Post ID.
Hi @jnicol
Thanks for the topic.
This is an interesting one, and one that I don’t yet have a solution for. Hopefully the following info can help shine some light on the problem.
To allow the ACF template functions such as get_field()
to work as expected within the block callback/template, we had to “inject” the block values into the “acf/pre_load_metadata” filter. This filter is run when ACF attempts to load a meta value for any given key/object_id.
This “injecting” behavior is overwriting/preventing your code from reading from the newly “setup postdata”.
I’ll have a think about how we can add compatibility with this function, but am not yet sure on the solution :S
This looks like an old thread but I wanted to make a quick bump to let you know it’s still happening. It’s popped up on me a few times, because I’m grabbing code from ACF Theme Code Pro, which makes me wonder if it’s in the docs somewhere.
Switching away from setup_postdata() to other methods seems to work fine.
I just ran in this this issue as well. A note about this Gutenberg issue in the documentation would be great: https://www.advancedcustomfields.com/resources/post-object/
Another bump – I’ve been tearing my hair out for a couple of hours trying to work out why it wasn’t working till I found this thread. Are there any temporary solutions to get round this for now?
I am also experiencing this issue. If there isn’t an easy solution, I would rather have to use something like get_field('size', $block_id)
to get block data than have to use get_field('post_field', get_the_ID())
for a post field.
Or, if possible for ACF to hook into the setup_postdata()
to switch contexts back and forth. I don’t know how feasible that would be.
Anyone who found a solution for this to work out? I have created a custom post type that contains some ACF fields and i want to pull those posts into a “carousel” block where i need to display that data.
Is this issue ongoing?
I can set post array using print_r()
and using $featured_post->ID
. Using setup_postdata($post)
is not working inside Gutenberg block.
Apparently @katie, it is still ongoing.
Today I had to add get_the_ID() to display a nested repeater from the post inside of a custom block.
@luiscolome confirmed via support ticket that the issue is ongoing. I’ve requested they add this to the documentation. It look me a bit of searching to find this forum post.
I think I’ve got the same problem outside of guttenberg blocks. I have a relationship field in a repeater but after doing the setup_postdata, I still see the original post details not the related post. I’ll try adding the postid and see if it works.
The simple solution I have for this is to declare a global variable in the single-post.php or single-[cpt].php file like this:
…
global $ref_post, $post;
$ref_post = $post;
get_header();
…
Then use the global $ref_post
wherever in the blocks you need to get the post info.
@brett I did something similar for an ACF block where I wanted to automatically show child pages, I set a var using $page_id = get_queried_object_id();
and used that var to set the post parent:
$page_id = get_queried_object_id();
$args = array(
'post_type' => 'page',
'posts_per_page' => -1,
'post_parent' => $page_id,
'order' => 'ASC',
'orderby' => 'menu_order'
);
$parent = new WP_Query( $args );
if ( $parent->have_posts() ) : ?>
This worked on the front end. Unfortunately for me this caused an issue in the WordPress admin – in WordPress admin screen all top level pages were showing. The slowed down my editing experience immensley so I instead opted to set the query using a tag instead of post parent.
The topic ‘Post Objects and get_field() in ACF Gutenberg Blocks’ is closed to new replies.
Welcome to the Advanced Custom Fields community forum.
Browse through ideas, snippets of code, questions and answers between fellow ACF users
Helping others is a great way to earn karma, gain badges and help ACF development!
We use cookies to offer you a better browsing experience, analyze site traffic and personalize content. Read about how we use cookies and how you can control them in our Privacy Policy. If you continue to use this site, you consent to our use of cookies.