Skip to content
This repository has been archived by the owner on Sep 27, 2023. It is now read-only.

setup_postdata() and global $post #177

Open
dashkevych opened this issue Aug 2, 2019 · 3 comments
Open

setup_postdata() and global $post #177

dashkevych opened this issue Aug 2, 2019 · 3 comments
Assignees
Labels
Type: Question This is a question regarding the functionality of the plugin.

Comments

@dashkevych
Copy link

dashkevych commented Aug 2, 2019

It seems like setup_postdata() does not work correctly if we does not use a global $post.

For instance:

The output will be correct when using this:

foreach ( (array) $featured_posts as $post ) :
	setup_postdata( $post );
	get_template_part( 'content', 'featured-post' );
endforeach;

wp_reset_postdata();

The output will be not correct when using this:

foreach ( (array) $featured_posts as $featured_post ) :
	setup_postdata( $featured_post );
	get_template_part( 'content', 'featured-post' );
endforeach;

wp_reset_postdata();

Example of using setup_postdata() with $post: https://github.com/WordPress/WordPress/blob/master/wp-content/themes/twentyfourteen/featured-content.php#L23

When using $post, the displays the following error: "Overriding WordPress globals is prohibited. Found assignment to $post".

What would you recommend in this case to avoid the error? Are we allowed to use setup_postdata()?

@dingo-d
Copy link
Member

dingo-d commented Aug 3, 2019

The context matters in this case 🙂

In which file are you using the $post variable? If it's in one of the templates, then you can use it just fine. In other files (like functions.php), since they are in global namespace, you risk of tampering with the global $post variable, and potentially affecting other places where it's used in WordPress.

You may wonder why this doesn't work, but it's actually because of the get_template_part and setup_postdata functions.
What get_template_part function does is it loads the template - tries to find it in different places before using locate_template which then uses load_template() to load the template while providing some globals:

    global $posts, $post, $wp_did_header, $wp_query, $wp_rewrite, $wpdb, $wp_version, $wp, $id, $comment, $user_ID;

Also the important part to note is the setup_postdata() function, that will set up global post data, won't override the global $post variable. For that to happen you would have to assign it to the $post variable which would trigger the message you've seen.

So, long story short: we currently have some issues with providing the context to determine if the 'globals' are actually global. When using templates, this can be ignored. In other places it's a legitimate concern.

TRT reviewers are aware of this, and they know when to ignore these issues.

@dingo-d dingo-d added the Type: Question This is a question regarding the functionality of the plugin. label Aug 3, 2019
@dingo-d dingo-d self-assigned this Aug 3, 2019
@joyously
Copy link

joyously commented Aug 3, 2019

If it's in one of the templates, then you can use it just fine. In other files (like functions.php), since they are in global namespace, you risk of tampering with the global $post variable

Be careful what you say here. Template files (single.php, archive.php, index.php, etc.) are in the global namespace. Look in template_loader.php and see that it just uses include ( $template ); from a file that isn't inside of any function.
It's template-parts that are loaded from a function and so their variables are local to that template-part. (but that function defines the globals as stated, so you can't use those names)

@dingo-d
Copy link
Member

dingo-d commented Aug 3, 2019

I stand corrected 🙂

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Type: Question This is a question regarding the functionality of the plugin.
Projects
None yet
Development

No branches or pull requests

3 participants