Opened 13 years ago
Last modified 5 years ago
#19572 new enhancement
switch_to_post() stack implementation (similar to switch_to_blog())
Reported by: | alexkingorg | Owned by: | |
---|---|---|---|
Milestone: | Priority: | normal | |
Severity: | normal | Version: | 3.3 |
Component: | Posts, Post Types | Keywords: | needs-refresh |
Focuses: | Cc: |
Description
One of the challenges themes and plugins have is the balance between utilizing the core APIs that rely on global variables, while leaving things in a "clean" state for the next worker in the chain.
For example, I might have a shortcode that pulls content from another post, outputs a title or some other data, then needs to restore the previous post environment. The attached patch provides APIs for doing just this - using the same stack approach that switch_to_blog() takes in a multi-site instance.
To set up a post context, call: switch_to_post($post_id);
This can be called multiple times, diving deeper into the stack. Then each process is responsible for restoring the $post context by calling: restore_post();
This goes back to the stack, bumps out the current post and restores the previous post's context.
There is some test code for demonstration here:
Attachments (1)
Change History (13)
#2
@
13 years ago
But what about in_the_loop()? Shouldn't it return false when switch_to_post() is called?
#3
@
13 years ago
I think this is interesting. It may be better (in terms of long-term architecture) to come up with something less procedural and more object-oriented (though also much more complicated), such as WP_Post coming back from the DB and get_post()/WP_Query, thus the ability to do $post->content(), $post->title(), etc. The various template tags would then need to be reworked to rely on the current $post global. It would be similar to how is_* methods work against WP_Query.
#4
@
13 years ago
Right, so then you wouldn't need to call switch_to_blog() at all. You could just call $whatever_post->content()
directly. Relevant ticket: #12267
#5
@
13 years ago
I'd say that as long as we have template functions for themes that rely on globals, something like this is needed.
#6
@
13 years ago
That's just the thing. You wouldn't need to use the template tags. They would be simple wrappers for the global. Think is_single()
and $wp_query->is_single()
.
You don't need switch_to_post() when you have access to all the posts at the same time:
$post_a = get_post( 1 ); $post_b = get_post( 2 ); $post_a->the_content(); $post_b->the_content();
But, since some of the filters on these template tags, such as 'the_content', do not pass the post id as a parameter, it's not that easy.
#8
@
13 years ago
I agree that when WordPress has posts that are meaningful objects with proper methods, etc (as proposed in #12267) that we should be able to use those methods. For now though, I think a switch_to_post stack would be helpful.
switch_to_post implementation