The Codex is quiet clear on this:
The query_posts() function is intended to be used to modify the main page loop only. It is not intended as a means to create secondary loops on the page. If you want to create separate Loops outside of the main one, you should use get_posts() instead. Use of query_posts() on loops other than the main one can result in your main loop becoming incorrect and possibly displaying things that you were not expecting.
UPDATE: All the above is true, but….
Both functions use the same WP_Query object. Practically this means different behaviors on different pages. If the page is an category archive the WP_Query object, which is used by the above functions side by side, contains other posts then on the frontpage. The behavior is still not as I expect it to be, but bottom line is that it isn’t what I expect from it. The next post on this page sumarizes the problem with indepth knowledge:
WP uses an object called
$wp_queryfor the main loop. We usually don’t see this object because it’s hidden behind
the_post()that are only wrappers for
If you want to modify the main loop you should use
query_posts()before the loop.
If you want another loop you can reutilize the
query_posts()before that new loop. This can be done many times if needed.
If for some reason you need to keep the $wp_query object around THEN you should use
WP_Query. And of course, because
the_post()are wrappers for
$wp_queryobject you can’t use them with
WP_Query. You should rather use
$sidebar= WP_Query('category_name= sidebar'); while( $sidebar->have_posts() ): $sidebar->the_post(); the_title(); the_content(); endwhile;
A good case where
WP_Querycould be better than
query_posts()is a left sidebar. As the code loop for the sidebar will probably be put on top of the main loop, a
query_posts()call will have changed the
$wp_queryobject and also changed the main loop. In this case to use
query_posts()at the sidebar code you will also need to use
query_posts()before the main loop to query the proper content for that loop.
So using WP_Query for this case will keep $wp_query and therefore the main loop untouched…..