If I'm making additional loops anywhere on a page—in the sidebar, in a footer, any kind of "related posts", etc—I want to be using
WP_Query(). I can use that repeatedly on a single page without any harm. (right?).What I don't know for sure
- When do I use @nacin's
pre_get_postsvs.WP_Query? Should I usepre_get_postsfor everything now? - When I want to modify the loop in a template page — lets say I want to modify a taxonomy archive page — do I remove the
if have_posts : while have_posts : the_postpart and write my ownWP_Query? Or do I modify the output usingpre_get_postsin my functions.php file?
tl;dr
The tl;dr rules I'd like to draw from this are:
- Never use
query_postsanymore - When running multiple queries on a single page, use
WP_Query - When modifying a loop, do this ________.
Thanks for any wisdom
Terry
ps: I have seen and read: When should you use WP_Query vs query_posts() vs get_posts()? Which adds another dimension —
get_posts. But doesn't deal with pre_get_posts at all.Answer:-
You are right to say:
Never usequery_postsanymore
pre_get_posts
pre_get_posts is a filter, for altering any query. It is most often used to alter only the 'main query':add_action('pre_get_posts','wpse50761_alter_query');
function wpse50761_alter_query($query){
if( $query->is_main_query() ){
//Do something to main query
}
}(I would also check that
is_admin() returns false - though this may be redundant.). The main query appears in your templates as:if( have_posts() ):
while( have_posts() ): the_post();
//The loop
endwhile;
endif;If you ever feel the need to edit this loop - use
pre_get_posts. i.e. If you are tempted to usequery_posts() - use pre_get_posts instead.WP_Query
The main query is an important instance of a
WP_Query object. WordPress uses it to decide which template to use, for example, and any arguments passed into the url (e.g. pagination) are all channelled into that instance of the WP_Query object.For secondary loops (e.g. in side-bars, or 'related posts' lists) you'll want to create your own separate instance of the
WP_Query object. E.g.$my_secondary_loop = new WP_Query(...);
if( $my_secondary_loop->have_posts() ):
while( $my_secondary_loop->have_posts() ): $my_secondary_loop->the_post();
//The secondary loop
endwhile;
endif;
wp_reset_postdata();Notice
wp_reset_postdata(); - this is because the secondary loop will override the global$post variable which identifies the 'current post'. This essentially resets that to the $post we are on.get_posts()
This is essentially a wrapper for a separate instance of a
WP_Query object. This returns an array of post objects. The methods used in the loop above are no longer available to you. This isn't a 'Loop', simply an array of post object.<ul>
<?php
global $post;
$args = array( 'numberposts' => 5, 'offset'=> 1, 'category' => 1 );
$myposts = get_posts( $args );
foreach( $myposts as $post ) : setup_postdata($post); ?>
<li><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></li>
<?php endforeach; wp_reset_postdata(); ?>
</ul>


0 comments:
Post a Comment