Opened 18 months ago
Last modified 17 months ago
#19572 new enhancement
switch_to_post() stack implementation (similar to switch_to_blog())
| Reported by: |
|
Owned by: | |
|---|---|---|---|
| Priority: | normal | Milestone: | Awaiting Review |
| Component: | General | Version: | 3.3 |
| Severity: | normal | Keywords: | has-patch |
| Cc: | nacin, matt@… |
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 (9)
alexkingorg
— 18 months ago
comment:2
scribu
— 18 months ago
But what about in_the_loop()? Shouldn't it return false when switch_to_post() is called?
comment:3
nacin
— 18 months 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.
comment:4
scribu
— 18 months 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
comment:5
alexkingorg
— 18 months ago
I'd say that as long as we have template functions for themes that rely on globals, something like this is needed.
comment:6
scribu
— 18 months 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.
switch_to_post implementation