Opened 16 years ago
Closed 16 years ago
#9854 closed defect (bug) (fixed)
wp_query gets poisoned by new WP_Query objects
Reported by: |
|
Owned by: |
|
---|---|---|---|
Milestone: | 2.8 | Priority: | normal |
Severity: | normal | Version: | 2.8 |
Component: | Query | Keywords: | |
Focuses: | Cc: |
Description
See #7080 and #9458 for reference material.
Code to duplicate the issue:
while ( have_post() ) { the_post(); the_title(); the_widget('WP_Widget_Recent_Posts'); the_content(); }
In the Recent Posts widget, add the following after the_post() to see things happening:
var_dump($GLOBALS['wp_the_query']->post->ID);
You'll notice is changes for no obvious reason.
Attachments (5)
Change History (34)
#1
@
16 years ago
- Summary changed from wp_the_query gets poisoned by new WP_Query objects to wp_query gets poisoned by new WP_Query objects
#2
@
16 years ago
Could we not use get_posts() here, do a regular foreach loop, and pass IDs/objects to the template functions?
#4
@
16 years ago
we could, and it might fix it, but there would remain the underlying issue -- i.e. why is wp_the_query getting changed at all? ;-)
D.
#6
@
16 years ago
WP::register_globals() does this:
$GLOBALS['post'] = & $wp_query->post;
Either removing that ref or breaking the ref in the_post() helps. Opted for ref break in [11382].
#7
@
16 years ago
good catch. will give it a shot. say, isn't this more prudent?:
unset($GLOBALS['post']); global $post;
#12
@
16 years ago
Confirming it does, but I'd like to request an additional tweak in order to spare myself a few nightmares with a separate plugin. Patch coming up in a sec.
#13
@
16 years ago
the suggested additional patch is to allow plugins to decide whether to do anything on loop_start/loop_end based on whether it's the main loop or not.
#16
@
16 years ago
Reports of breakage for loops like this:
$recent = new WP_Query("blah=blah"); while($recent->have_posts()) { $recent->the_post(); echo $post->ID; }
Evidently, $post is not being set.
#19
@
16 years ago
mm, anything more specific? because this essentially is exactly what the recent posts widget does. :-P
#21
@
16 years ago
The problem loop is in sidebar.php, which is loaded through get_sidebar() -> load_template(). load_template() sets up a $post global for use by sidebar.php, but we're stomping that global.
#22
@
16 years ago
global $post creates a ref. We unset GLOBALSpost? in the_post(). The global $post used by sidebar.php now points at nothing.
#23
@
16 years ago
Stick a loop in sidebar.php of the default theme to see:
$recent = new WP_Query('showposts=10'); while ( $recent->have_posts() ) { $recent->the_post(); var_dump($post); }
$post never changes
#24
@
16 years ago
Removing the ref from WP::register_globals() seems to fix everything. We can keep global $post as a ref for everyone to use without it messing with queries.
#27
@
16 years ago
uploaded a diff for test cases and a slightly different patch (I moved the new the_post hook to a place where it's more useful on singular pages)
Fix for Recent Posts widget.