post-page

Define Your Own WordPress Loop Using WP_Query

78
responses
by
 
on
April 13th, 2008
in
HOW-TO, WordPress FAQs, WordPress Hack

We all know what the WordPress Loop is right? If not, there are many great tutorials around the web that explain the WordPress Loop.

One of the easiest ways to navigate and manipulate the loop is to use the function called query_posts. Nathan Rice calls it a WordPress developers best friend.

When you use query_posts, however, you risk the following:

  • Potential to interfere with plugins which make use of the Loop.
  • Potential to invalidate WordPress conditional tags.
  • Having to deal with resetting, rewinding, offsetting…

I say skip query_posts. In a way you’ll still be using it, but the better (and sometimes easier) technique is to instantiate your own WP_Query object and create your own loop.

Creating Your Own Loop With WP_Query

The first step is to instantiate your own variable using the WP_Query class.

What we’ll be doing in this example is creating a common feature on blogs, which is to display a list of the recent articles.

<?php
    $recentPosts = new WP_Query();
    $recentPosts->query('showposts=5');
?>

All I’ve done in the above code is defined a variable named recentPosts and instantiated an instance of WP_Query.

I then used a method of WP_Query to start a query (pretty much the same thing as using query_posts). You even use the same usage parameters as query_posts.

Now it’s time to start our own loop:

<?php while ($recentPosts->have_posts()) : $recentPosts->the_post(); ?>
   <!-- do some stuff here -->
<?php endwhile; ?>

Notice the use of the recentPosts variable to start the loop. We utilize two methods of WP_Query, which is have_posts and the_post. You can read more about those two methods on my article Global Variables and the WordPress Loop.

The beauty of this is that once you are inside your own loop, you can use the standard post tags.

The Full Code

Here’s the full code for showing the last five recent posts using your own loop:

<h3>Recent Articles</h3>
<ul>
<?php
    $recentPosts = new WP_Query();
    $recentPosts->query('showposts=5');
?>
<?php while ($recentPosts->have_posts()) : $recentPosts->the_post(); ?>
    <li><a href="<?php the_permalink() ?>" rel="bookmark"><?php the_title(); ?></a></li>
<?php endwhile; ?>
</ul>

Update: Using Pagination

This comment is from Aaron Harun

@Ron and Monika

If you use the query:

$recentPosts->query('showposts=5'.'&paged='.$paged);

it will automatically page the wury based on the page number passed
through the url eg “/page/4″

However, this doesn’t work with the “post_nav_link” function because it
only checks the $wp_query variable. To get around this you have to
trick the function by switching $wp_query on it. Add the first block
before your custom loop and the second after to achieve this effect.

<?php //query_posts('paged='.$paged);
$temp = $wp_query;
$wp_query= null;
   $wp_query = new WP_Query();
   $wp_query->query('showposts=5'.'&paged='.$paged);
?>

<?php $wp_query = null; $wp_query = $temp;?>

Thanks Aaron for the contribution.

Conclusion

Defining your own loop using WP_Query is an easy way to run your own custom queries without interfering with the default Loop. It’s also a great way to run multiple loops that are completely independent of each other.

WordPress Resources mentioned:

heading
heading
78
Responses

 

Comments

  1. Monika (40 comments.) says:

    Hi Ronald
    I have a great wish:
    This way is killing the next and previous link. Please show this loop with full functionable pagination or “thousands” ;) of support threads will be open….pagination doesn’t work for me

    thanks a lot
    Monika

  2. Ronald Huereca (66 comments.) says:

    Monika,
    I’m afraid I don’t know the answer to that. It looks like from the pagination code that it ties into the default loop.

    It appears that you’ve found a weakness of this technique over query_posts. To be honest, I don’t think you’d really want to use pagination with this type of technique, which should be independent of the standard WordPress loop.

    Perhaps someone else can chime in?

  3. Monika says:

    Hi Ronald

    To use this loop in index.php doesn’t make sense, so I try it in archive.php , WP has the order to show 10 articles per page,

    with this loop it shows 5 recent posts and 5 from the archive, because to combine two loops with if have posts …while … WP dig one’s heel in and says: 10 articles are 10 articles ;)

    I have this day no time to play with your loop, but if someone would like to us it he must be aware of this ;)

    kindly regards

    Monika

  4. Darryl (7 comments.) says:

    I’ve used this method for the index page to separate a featured post:


    $my_query = new WP_Query('cat=-1&showposts=1');
    while ($my_query->have_posts()) : $my_query->the_post();
    $do_not_duplicate = $post->ID;

    ... do stuff here ...

    endwhile;

    and further down show the rest of the posts

    if (have_posts()) : while (have_posts()) : the_post();
    if( $post->ID == $do_not_duplicate ) continue; update_post_caches($posts);

    .. do stuff here ...

    endwhile;

    ...pagination...

    else;
    endif;

    The only way that I could get pagination to work was to remove one category from showing…so I chose the default uncategorized category. Since I wanted every post being under a category that I defined, it really wasn’t an issue.

  5. Darryl (7 comments.) says:

    I forgot to mention that with this I was also using WP-Sticky to “sticky” the featured post (sticky for single day, announcement for multiple days). Without this plugin it would just show the latest post in the featured post area.

  6. Leland (16 comments.) says:

    @Monika: Thanks for that technique. I was wondering a more effective way to separate a featured post from the rest of the loop.

  7. Monika says:

    oh there was a fatal error if I tried to send my comments before , so I’ll try it again

    @ Leland there is no loop from me in this comments

    I know 5 ways to highlight the first post
    http://www.texto.de/texto/5-wa.....ess-theme/

    and here is my loop for the last 5 posts with pagination

    OH! it is my code I’ll try it in another way


    Recent Articles

    rewind_posts();
    $wp_query->query_vars["showposts"] = 5;
    $wp_query->get_posts();
    if (have_posts()) : while (have_posts()) : the_post(); ?>
    ...your stuff


    endwhile;

    …next_posts_link(‘« Older Entries’) …
    .. previous_posts_link(‘Newer Entries »’) ….


    endif;

    regards Monika

  8. Nathan Rice (18 comments.) says:

    Ronald,
    You’re absolutely right. query_posts kills your other loops (if using multiple loops). I’ve been using the alternate technique for about 6 months now, and it works great!

    And as far as I know, pagination only works with the default loop. It’s best to use conditional tags to qualify the standard loop if you want to keep pagination. For instance, if you want to exclude a category from the standard loop, then do this:

    if have posts : while have posts : the post
    if(!in_category(‘2′)) :
    standard stuff like title and content
    endif
    endwhile
    endif

    That excludes any post that is in category 2 from being displayed. Pretty easy.

  9. Thaya Kareeson (51 comments.) says:

    Thank you for the guide!

  10. Ronald Huereca (66 comments.) says:

    Thanks everyone for their input. I’ve amended the post with some further input.

  11. Julian Johannesen says:

    Thanks, Ronald. This was really helpful. Is there any chance you could go into more detail about how the pagination workaround works?

  12. WP Modder (1 comments.) says:

    Great and informative post. I’ve been learning and modifying the loop myself by following other tutorials, this is a great addition. Like Julian above, I would like to learn more about the pagination workaround though. It seems like a really great feature, especially if a page has many different loops running. Paging results seems like a really great user experience.

  13. Ronald Huereca (66 comments.) says:

    @Julian, WP Modder,
    That would probably require a separate post for the explanation. I’ll see what I can do.

  14. Herbert (1 comments.) says:

    Thank you! Good guide and a perfect way to run multiple independent loops.

  15. Tim Wheatley (1 comments.) says:

    I use this on my site for the listing of posts on the main page, with two wp_query loops on the right side of the page. Then in my sidebar (left side) I use it for the quick thoughts (or asides as everyone calls them), the latest gallery and latest panoramic image.

    So all in all when you view the main page of my Web site, that is five wp_query post loops.

  16. Kashif (1 comments.) says:

    How to fetch posts based on custom fields. I want to show posts that contain similar custom field value, using WP loop (so that pagination work).

  17. Jack (1 comments.) says:

    This has been wonderfully helpful and clear! One q. How do I set up a query with alphabetizing and pagination?
    Many thanks!

  18. Sepehr Lajevardi says:

    You save my life! thanks ;)

  19. bazzle83 (1 comments.) says:

    You are a godsend, thanks for your clear explanation.

  20. Adam Foster (1 comments.) says:

    How can I add a “New” image beside the latest 5 posts?

  21. Ariah Fine (1 comments.) says:

    This is great, and I’ve got it working well on my site currently.
    But, I’d much rather have it show posts in the same category as the post I’m viewing or posts with a similar tag. Is there a way to put variables in to the Wp_query (like tags or category of current pst)? I looked at the codex and it seems like there is I just didn’t understand what it would look like implemented in your example above.

  22. RavanH (11 comments.) says:

    Hi Ronald,

    THANK you for this excellent (simple but effective) how-to. I am working on a theme front page using home.php where I use your technique to create serveral sections with different loops.

    One section listing all sticky posts:

    query(array('post__in'=>get_option('sticky_posts')));
    while ( $stickyPosts->have_posts() ) :
    $stickyPosts->the_post(); ?>

    <?php
    endwhile;
    endif;

    [ NOTE: I use if (get_option('sticky_posts')) instead of if ( $stickyPosts->have_posts() ) here because if there are NO sticky posts, this loop would just bluntly burp out all posts! Any ideas on why that happens? ]

    Another listing just one category called News (if there is any):

    term_id) :
    $newsPosts = new WP_Query();
    $newsPosts->query("cat=$news_cat&showposts=3&caller_get_posts=1");
    if ( $newsPosts->have_posts() ) :
    while ( $newsPosts->have_posts() ) :
    $newsPosts->the_post(); ?>

    <?php
    endwhile;
    endif;
    endif;

    I found that just doing multiple query_posts() will make WP ‘forget’ stuff e.g. it is doing a frontpage and suddenly conditional tags like is_front_page() or is_home() don’t work anymore. So your method came as a BIG lifesaver!

    One question: Using several query_posts() gets me strange WP behaviour but I bet I could have chosen another route. What if I just took the unmodified main loop query and did several loops with conditional tags (like if( in_category(‘2′) ) for instance) to weed through all posts and exract only the ones I need for that particular section. And after each section do a rewind_posts() to set the loop back to start again… But I suspect this will be much more resource intensive when the blog is filled with hundreds of posts, or am I mistaken?

    • RavanH says:

      Wow, it seems a lot was lost from between the tags in my previous post... Ronald, could you moderate it? I will try to enter the two code examples again (now a bit simplified) in the hope it will get through this time :)

      ...
      One section listing all sticky posts:
      if (get_option('sticky_posts')) :
      $stickyPosts = new WP_Query();
      $stickyPosts->query(array('post__in'=>get_option('sticky_posts')));

      while ( $stickyPosts->have_posts() ) : $stickyPosts->the_post(); ?>

      ...sticky loop stuff here...

      endwhile;
      endif;

      ...

      Another listing just one category called News (if there is any):

      if ($news_cat = get_category_by_slug('news')->term_id) :
      $newsPosts = new WP_Query();
      $newsPosts->query("cat=$news_cat&showposts=3&caller_get_posts=1");

      if ( $newsPosts->have_posts() ) : while ( $newsPosts->have_posts() ) : $newsPosts->the_post(); ?>

      ... news loop stuff here ...

      endwhile;
      endif;
      endif;

      Thanks!

  23. Luke says:

    Hi,

    Thanks for the tutorial, very straight forward. So I tried this out on a page template of mine. The first loop is right from the original theme template and displays whatever the user has typed into a published page.

    The second loop using your technique and calls a number of posts which are defined by 3 custom fields the user can set before publishing the page.

    query(array(

    ‘showposts’ => 500,
    ‘category_name’ => $record_category = get_post_meta($post->ID, ‘record_category’, TRUE),
    ‘meta_key’ => $record_metakey = get_post_meta($post->ID, ‘record_metakey’, TRUE),
    ‘meta_value’ => $record_metavalue = get_post_meta($post->ID, ‘record_metavalue’, TRUE),
    ));

    ?>

    So far so good, the **DO STUFF** that follows work brilliantly and I get all the records I’ve asked for. Problem is WP gets mixed up as to where it is. Instead of decided it’s looking at a specific page, it thinks it’s looking at the last entry from the second WP_Query loop.

    Any ideas how I can fix this? Thanks again,

    Cheers – Luke

  24. Luke says:

    I tried using the method described by Aaron Harun as well but that didn’t seem to work. This is what I tried using his template.

    // First Loop

    // Second Loop (below)

    query(array(

    ‘showposts’ => 30,
    ‘category_name’ => $record_category = get_post_meta($post->ID, ‘record_category’, TRUE),
    ‘meta_key’ => $record_metakey = get_post_meta($post->ID, ‘record_metakey’, TRUE),
    ‘meta_value’ => $record_metavalue = get_post_meta($post->ID, ‘record_metavalue’, TRUE),
    ‘paged’ => $paged,
    ));?>

    **** Do stuff ****

    *** Navigation Code ****

  25. Diego Herrera says:

    I found a simple solution for the pagination problem and the comments problem.

    just add this

    global $wp_query;
    $wp_query=$the_query;

    next to you query, where $the_query = new WP_Query(….

    Thats all

    • daft says:

      hi diego,

      can you help here? i did what you mentioned but can get the next prev article links to work
      thanks

  26. jamie says:

    Thanks for the code buddy. this ended a 4 hour search to this problem. I tried to add the code to show the previous post and next post and it errored out on the endif. Can you recommend a fix for that? I only want to show about three posts and have a link for the rest.

  27. Steve Taylor (8 comments.) says:

    Thanks for a really useful article. I’ve just put together a function for my custom themes that improves on WordPress’ built-in pagination controls. It accepts any WP_Query object as a parameter, so it can be used with this technique (without the documented pagination issue), or with normal WP loops…

    • Steve Taylor (8 comments.) says:

      There’s some linked text in the above comment! Doesn’t seem to be to clear to me, thought I’d point it out…

  28. Loren says:

    Will the the following code as found in “Update: Using Pagination” work in php5?
    query(‘showposts=5′.’&paged=’.$paged);
    ?>

    As $wp_query is an object, and in PHP4, objects are passed by value while in php5 they are passed by reference will that cause a problem since $temp points to the same object in memory as $wp_query?

  29. Josh says:

    Great post!!!

    Would you know how to grab the two most recent posts (with excerpt), then show the next three post titles (Just the Titles)?

    Thank you!

  30. joyoge designers' bookmark (1 comments.) says:

    very helpful loops from wp query. thanks for the post..

  31. Mobile Broadband (1 comments.) says:

    Thanks for this! I’ve been working for 6 hours straight playing with query_posts and wasn’t getting anywhere. My problem was that I wanted to show posts on a ‘page’ and had already used two loops. When you want to show posts on a page, you have to save the initial query before starting a second loop to show your posts, then when youre finished, reloading the original query…

    The problem with doing this was that I wanted to add category posts to my footer so any additional query posts were only calling ‘pages’ or nothing at all.

    Your tutorial helped me start a new loop for the footer and now I’m flying! Thanks, man!

  32. Fahad (1 comments.) says:

    Hello Great article .
    I hope you can help me with something i did all that but the problem is in main page showing recent posts and in page/2 page/3 etc showing same content i want to show old posts as well can you please tell me how to do that thanks in advance .

    Fahad

  33. Tiff says:

    Thank you for the code, it is the easiest one I’ve seen so far…

  34. Aery (1 comments.) says:

    Hi Ronald,

    Thanks for the exellent trick with WP_Query. I hope you can help me with basic problem on wordpress loop.

    I intend to make a custome query which will showcast only featured posts in my homepage. However, as on using custom query, pagination doent seem to

    work.

    The custom query is –

    have_posts()) : $recent->the_post();?>

    *** Do some stuff ***

    Now, the problem is even after clicking “Older Entries” or “Newer Entries”, the page URL changes to domain.com/page/2 but the contents remain same.

    It looks like pagination isnt working with WP_Query.

    I would be really greateful if you can suggest something to make it work.

  35. Thomas says:

    I’m liking this method. Any way to include an image that may already be placed within the article? Maybe get a little ol’ thumbnail or something. It seems many people are doing this as well. Anyone know how to do this?

  36. Aery (1 comments.) says:

    Can someone help with this http://weblogtoolscollection.c.....nt-1319071

  37. Jason says:

    Hi there,
    How would I display the following within this query – & in this order;

    the post date
    the post title (which is a link to the post)
    the post excerpt
    and a read more link

    thanks in advance!
    Jas

  38. Sergei Plaxienko says:

    Many thanks for help, it really helped! :)

  39. Bhargavi says:

    Why? Oh why didn’t I find this in the morning? My comments pagination was broken on index.php because of my multiple loops. I was resetting the wp_query but after the comments. It took me 8 hours to fix this and I still have some more problems – the post pagination is not working and the comments Next button takes me to single.php

  40. Bill Lowden (1 comments.) says:

    Sweeeet! and easy. I was trying to accomplish this with query_posts and it was messing up the loop by pulling the news section into the featured posts section. This is easier and it works.

  41. Dasha (1 comments.) says:

    Thanks for the post, very usuful.

    I’ve got a question. Is it possible to loop through the results of WP_Query without the line $recentPosts->the_post(); because that one overwrites the global $post, which I want to preserve as I need to use the original $post after the custom loop. Hope that make sense.

    Would really appreciate any help!
    Thanks.

    • Shah Rukh (2 comments.) says:

      Yes its possible but it depends how you want to bend the loop according to you… Dasha May i know what type of change are you trying.. :)

  42. Shah Rukh (2 comments.) says:

    Awesome!!!! One more addition to my favorite WP blogs…. Thanks :)

  43. Beth (2 comments.) says:

    I have a question. I have the custom loop working but I need it to sort by certain categories in alphabetical order. Any suggestions on how I can accomplish this?

    I am a beginner at PHP so any help would be great!

  44. RW says:

    I’m trying to use this code with pages and it still shows me posts. I have read the codex but cannot make this work… Anyone?

  45. Rakhmad says:

    Oh, God!

    ” … because it only checks the $ wp_query variable …”

    Thanks It’s very helpfully!

  46. Sophia says:

    how do i exclude two categories using the wp_query loop?



Trackbacks/Pingbacks

  1. […] ????? Define Your Own WordPress Loop Using WP_Query?????? […]

  2. […] The technique I use makes use of two custom functions placed in a theme’s “functions.php” and a custom WordPress Loop. […]

  3. […] Define Your Own WordPress Loop Using WP_Query ** Posted using Viigo: Mobile RSS, Sports, Current Events and more ** We all know what the WordPress Loop is right? If not, there are many great tutorials around the web that explain the WordPress Loop. […]

  4. […] Weblog Tools Collection » Blog Archive » Define Your Own WordPress Loop Using WP_Query (tags: wordpress loop wp_query php theme blogging development howto) […]

  5. […] Define Your Own WordPress Loop Using WP_Query (tags: wordpress) […]

  6. […] Weblog Tools Collection » Blog Archive » Define Your Own WordPress Loop Using WP_Query Så simpelt, så simpelt. Dette kan jeg bruge mange steder, hvor wp_query kommer i konflikt med noget andet. (tags: wordpress loop wp_query howto tutorial)   […]

  7. […] Define Your Own WordPress Loop Using WP_Query – WTC Så gör du en alternativ loop i dina WordPress-mallar. (tags: wordpress loop php theme howto) […]

  8. […] Weblog Tools Collections, come creare il proprio loop WordPress e visualizzare solo alcuni post in base ai valori dei custom […]

  9. […] Define Your Own WordPress Loop Using WP_Query (tags: wordpress code php) […]

  10. […] from this blog via email.Last week I published two articles using custom loops. The first was about how to create a custom loop. The second was how to retrieve posts based on custom fields. In both articles, several readers […]

  11. […] un peu plus votre blog. De la même trempe que celui présenté au dessus, ici, on vous propose de créer une boucle WordPress entièrement grâce aux Query Posts et de récupérer des articles via les champs personnalisés de WordPress, les fameux “Custom […]

  12. […] Weblog Tools Collection » Blog Archive » Define Your Own WordPress Loop Using WP_Query (tags: wordpress) […]

  13. […] Weblog Tools Collection » Blog Archive » Define Your Own WordPress Loop Using WP_Query (tags: wordpress php wp_query tutorial theme) […]

  14. […] Weblog Tools Collections, how to create your own WordPress loop and how to retrieve posts based upon custom fields […]

  15. […] Define Your Own WordPress Loop Using WP_Query […]

  16. […] ????? Define Your Own WordPress Loop Using WP_Query????? […]

  17. […] <br /> <?php endwhile; ?> </div> A deeper discussion in how to do this is on the Weblogs Tools Collection (where I found the solution). The lesson here is, in order to avoid conflicts with WordPress […]

  18. […] going to get serious about rolling your WordPress queries I highly recommend you follow Mark Ghosh’s advice on initializing another object of the WP_Query class and using the query method, rather than just […]

  19. […] posts need to be outputted on those specific loops.This is a good explanation on how it works: Define Your Own WordPress Loop Using WP_Query | Weblog Tools Collection […]

  20. […] Define Your Own WordPress Loop Using WP_Query […]

  21. […] Define Your Own WordPress Loop Using WP_Query […]

  22. […] Define Your Own WordPress Loop Using WP_Query – A great hack to creating your own customized WP loop. […]

  23. […] If you want to display more or less than five posts, simply change the value of the showposts parameter on line 3. Source Article : http://weblogtoolscollection.c.....-wp_query/ […]

  24. Zack Live says:

    The Power of WP_Query…

    WP_Query is a powerful tool to control what to display on your blog. This is very useful for plugin and theme designer, especially for magazine style themes which need to display posts of different categories in different sections. In this post, I will…

  25. […] Define Your Own WordPress Loop Using WP_Query […]

  26. […] Define Your Own WordPress Loop Using WP_Query […]

Obviously Powered by WordPress. © 2003-2013

page counter
css.php