WordPress.org

Make WordPress Core

Opened 6 years ago

Last modified 20 months ago

#19572 new enhancement

switch_to_post() stack implementation (similar to switch_to_blog())

Reported by: alexkingorg Owned by:
Milestone: Awaiting Review 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:

https://gist.github.com/1309915

Attachments (1)

patch.diff (919 bytes) - added by alexkingorg 6 years ago.
switch_to_post implementation

Download all attachments as: .zip

Change History (13)

@alexkingorg
6 years ago

switch_to_post implementation

#1 @scribu
6 years ago

This would definitely come in handy. +1

#2 @scribu
6 years ago

But what about in_the_loop()? Shouldn't it return false when switch_to_post() is called?

#3 @nacin
6 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 @scribu
6 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 @alexkingorg
6 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 @scribu
6 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.

#7 @bigdawggi
6 years ago

  • Cc matt@… added

#8 @bigdawggi
6 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.

#9 @chriscct7
4 years ago

  • Keywords needs-refresh added; has-patch removed

#10 @DrewAPicture
3 years ago

  • Component changed from General to Posts, Post Types

This ticket was mentioned in Slack in #core-multisite by jjj. View the logs.


23 months ago

#12 @swissspidy
20 months ago

Why introduce a temporary solution using switch_to_post() when the goal is to have proper methods as suggested in #12267?

Note: See TracTickets for help on using tickets.