If..Else Log

Query_posts redux

As I've mentioned before, the query_posts() function can be used to repopulate the values of the query_object. However, as the codex entry for this function is currently empty, I'd thought it may be helpful to list some of the arguments that you can pass to it.

I'll start with the one that I mentioned in the earlier post, category_name. This allows you to retrieve entries in the category named. However, there's also another parameter that you can use for the same task; cat.

There are two differences between cat and category_name. The most immediately obvious difference is that cat works on the category_id rather than the name. You may be thinking at this point, "what's the point then? I might as well use the more readable category_name." However, there is another trick that you can do with cat. When passing in the catgory_id, if you instead stick a - in the front, this will instead have the effect of excluding that category.

For example, if you make the following call:

  1. <?php
  2. query_posts('cat=-1');
  3. ?>

This will exclude all the posts that belong only to category 1. There is a proviso however, and it's a fairly big one. Note that I said "that belong only to category 1″. Due to (what I believe is) a flaw in how the query is constructed, if a post belongs to another category as well, it will still be picked up.

You can also restrict the posts by author. If you're running a multi-author blog and want only posts from a single author showing up on the front page, you can use the parameters author_name or author. author_name operates on the user_nicename field, whilst author operates on the author id.

You can also retrieve a single post or page. Why would you want to? Simple. As a consequence of the template hierachy, home.php executes first. This means that you can write a home.php which calls query_post to retrieve a particular page and set that to be your front page. Without any plugins or hacks, you've got a mechanism to run, show and maintain a non-bloggy front page.

To do this, you would use the following parameters. If you want a post to be your front page, you can either use p or name. p is the post-id whilst name would be the post-slug e.g.the following two are equivalent

  1. <?php
  2. query_posts('p=1'); //using the postid to show the first post
  3. query_posts('name=first-post'); //using the post slug to show the first post
  4. ?>

More useful perhaps would be to take advantage of WP's new page functionality and use that for you front page. You could perhaps set your about page to be the entry point or maybe your sites colophon. You might even do something a bit more dynamic and set a custom page that shows a list of the latest comments, posts, categories and archives but I digress. To retrieve a particular page, you would use the following:

  1. <?php
  2. query_posts('page_id=7'); //retrieves page 7 only
  3. query_posts('pagename=about'); //retrieves the about page only
  4. ?>

How about returning all the posts from a particular time period? Well, in that case you can use the parameters hour, minute, second, day, monthnum and year.
These all take a number that represent the appropriate unit of measure. The only one which necessitates a bit of explanation would be day which is asking for the day of the month.

  1. <?php
  2. query_posts('day=15'); //retrieves all the posts that were posted on the 15th
  3. ?>

The paged parameter can be used to return all the posts for that given page number e.g. if you've configured WP to display 10 posts and you call paged=2, you would get the posts that would normally be on the second page e.g. posts after the first 10.

And finally, we come to the orderby parameter. This, not surprisingly, allows you to change the ordering of posts. By default, WP returns posts in the usual blog pattern: reverse chronological ordering i.e. latest posts first.

This is the same as calling

  1. <?php
  2. query_posts('orderby=date');
  3. ?>

However, what you can also is order by the author or title:

  1. <?php
  2. query_posts('orderby=author');
  3. query_posts('orderby=title'); //returns all the posts in reverse alphabetical order
  4. ?>

Actually, I'll mention one more parameter: posts_per_page. This one will allow you to set the number of posts you want to retrieve for a given page which means that you make WP only show the latest post on the front page.

What's more, if you want to retrieve every single page (perhaps for a custom archive page or a full article listing), you can set this to -1.

  1. <?php
  2. query_posts('posts_per_page=-1'); //returns all the posts without pagination
  3. ?>

Anyways, that's it for today. This post was primarily written for my own benefit but it will hopefully be useful to others. Feel free, of course, to add any suggestions or feedback via the comments form. If you're looking for an example on how to use the function, it may be helpful to look at the first post I made on the subject.

-30-

41 Responses to “Query_posts redux”

  1. Gravatar Koray April 8th, 2005 7:35 pm

    Genius. I was thinking of writing a WordPress based CMS. This makes it much easier.

  2. Gravatar matthew April 9th, 2005 2:05 pm

    thank you, thats excellent. I should be able to tidy up my hacked sandbox files now and remove all the ifs and else :-D

  3. Gravatar matthew April 10th, 2005 3:30 pm

    :-( hmm, yes. due to this

    “There is a proviso however, and it’s a fairly big one. Note that I said “that belong only to category 1″.”

    It’s not THAT useful, but still Ive managed to tidy up some code.

  4. Gravatar Make WP show only one post on the front page - If..Else Log April 10th, 2005 4:11 pm

    […] forum asked if it was possible to only show a single post on the front page. Thanks to the query_posts, and the template hierachy, this can be done fairly easily without res […]

  5. Gravatar somefoolwitha.com » Sandbox getting full April 10th, 2005 6:53 pm

    […] t today tidying up some bits I wasnt happy with and simplifying my files, thanks mainly to Phu Ly’s post. Also, thanks to a […]

  6. Gravatar Brendan April 17th, 2005 6:33 am

    Phu,

    I’m trying to work something out with this.

    I’ve figured out how to use home.php following your suggestions to get a single post.. I then link into that another php to display a single category (asides) then the “rest” of the posts using the excerpt function to display a portion of each.

    Which ends up with the following flow:

    Latest Post –> Asides –> first post(again) + rest of posts

    What I want to achieve is:

    Latest Post –> Asides –> (first post skipped/ignored) then rest of posts

    Obviously I need to use a combination of `query_posts(’posts_per_page=1′);` along with 2 additional query_posts to
    1) pull out the asides category, then

    2) display the rest of the posts in chronological order minus the latest post (as it has already been displayed).

    I’m thinking it will involve using the query function to display the first page, then query again to display asides, then a final query to again pull the first post (which won’t be displayed a second time round), then use an else to continue displaying the rest of the posts (minus the asides of course).

    Any suggestions as to how I can achieve this? My understanding of how to nest these various query’s a bunch of if - else if - else loops is screwing with my mind. :)

  7. Gravatar Phu April 17th, 2005 1:24 pm

    There’s a few ways you can do this and it depends on how you want to structure your code. One way is probably to maintain two query_objects.

    Loop through the_loop as normal for your first post. Maintain a counter for how many times you’re going through and on your second time round, create a *new* query_object e.g.

    while (have_posts()) : the_post();
    if ($counter==1){
    $my_query = new WP_Query('category_name=asides&showposts=10');
    while ($my_query->have_posts()) : $my_query->the_post();
    // Do stuff for asides.
    endwhile;
    }
    //Do regular post stuff
    endwhile;

    The subsequent work can continue to be handled normally (i.e. by the same process as the first post).

  8. Gravatar Brendan April 17th, 2005 2:18 pm

    Interesting..

    So basically the counter causes the first post to be skipped (due to the if statement being false for the first post) then proceeds to be true for the remainder (spitting out the asides).

    Once that is complete, the endwhile kicks in, at which point the final block runs, but due to the aforementioned counter being in the same while loop (have I got that right?) it will thus skip the first post (again) due to that being false, before finally drawing out the final post list.

    I may not be quite right there, but I can see basically how the structure works, so I should be able to explode that nicely.

    Effectively I can use your nifty tutorial on using home.php to dredge out the first post, then run this block perhaps in the second php file to “assemble” the asides and recent posts..

    Excellent! Thanks :D

  9. Gravatar Brendan April 18th, 2005 12:12 pm

    Hrm, I’ll have to do a bit more research on using a counter, as whenever I try to use it, nothing displays.

  10. Gravatar clint April 21st, 2005 9:27 pm

    wow excellent writeup, this is info ive been trying to collect for quite a while now thanks!

  11. Gravatar Root April 23rd, 2005 12:51 am

    Brilliant. You have really added in the technical detail necessary to deliver really powerful additional functionality. On a sour note - I do find it a bit odd that a very powerful tag like this, which has strategic design implications is not documented better at codex. And on a really sour note one of the devs php examples includes it which is how I found it. So many people in the forum are flailing looking for this. And incidentally many folk do not appreciate that the query runs outside the loop. Just think what we can do with that. Its nice to be over the bleeding edge for a change.

  12. Gravatar Phu April 23rd, 2005 1:19 am

    I’ve been meaning to fill up the entry in the codex but haven’t been able to get round to it just yet. I don’t suppose anyone fancies the job of doing this?:-)

  13. Gravatar Steve April 30th, 2005 5:44 pm

    I’ve been using the multiple loop trick with much success, but how would I get a query form multiple categories? for example, right now I have:

    query_posts(’cat=1&showposts=4′) and I would like to have something like:
    query_posts(’cat=1&cat=2&showposts=4′) so the loop shows the latest posts from those two categories. Obviously the above syntax doesn’t work. What will?

    Thanks.

  14. Gravatar jaya May 17th, 2005 12:25 pm

    How do we know the meaning of each parameter? I’ve seen some paramaters in wp-blog-header.php, but I still don’t know how to use it, e.g 'm', 's', etc.

  15. Gravatar Moshu May 19th, 2005 9:02 pm

    Hi, I have a similar problem that was described by Brandon, except I don’t use asides. So, basically I am calling the last post from X category with a query_post in a similar layout like here (i.e. at the top in its own div).
    Then I was trying to have the rest of the posts below - using the “original” Loop. It didn’t work, so I used again the query_posts, but I don’t know how to exclude the one post called before. I can exclude the whole category (with the “-” in front), but I’d like to show the rest of the posts from cat X.

  16. Gravatar indi May 24th, 2005 11:59 am

    Query Posts seems to reset the counter. If used before the normal loop, that’ll display ’sorry no post found’. How do you reset the counter so that the normal loop can run?

  17. Gravatar Boris June 13th, 2005 10:34 pm

    How about
    query_posts(’children_of_cat=1′)
    and not requiring that the entries called by it be themselves marked as being in Category “1″? (Since I am assuming that somewhere in it’s DB, WP knows that children categories are children of.
    Why? This would allow for the semblance of multiple “blogs”.
    Maybe I’m just too much of a newbie to WP to see the obvious way to do this with current WP functionality? :(

    ;)

  18. Gravatar Josh June 14th, 2005 3:34 pm

    How do I get a list of recent posts (say 7) to display on a WP Page? I want only the 7 most recent. The reason I ask is I’d like a static Page up front and my recent blog entries on a seperate WordPress Page. I can’t figure out how to accomplish that. Query_Posts seems very close to what I want but I’m not quite sure how to use it to accomplish what I’m after on a Page.

  19. Gravatar Stuart July 10th, 2005 9:41 am

    I just found an unintended side effect of query_posts.

    I am using WordPress 1.5.1.3 with the default Kubrick theme. I wanted to exclude everything from my category 2 from the front page, so I used query_posts(’cat=-2′).

    Unfortunatly this breaks the functionality of another part of WordPress.

    Down the bottom of the front page is a link to “Previous Entries”. Normally, clicking on this displays the next most recent entries that did not appear on the front page. If the above query_posts line is added, it shows *exactly the same* content as the front page.

    This bug was also present in the original version of WordPress 1.5.

    Cheers,
    Stuart.

  20. Gravatar Steven August 19th, 2005 8:53 pm

    Yeah.. I’ve noticed the paging / counter reset problem with query_posts() too. The query_posts() doesn’t work with paging… anyone know of a solution?

  21. Gravatar Steven August 19th, 2005 9:00 pm

    Actually, a quick google search has revealed the following solution to the lack of paging when using query_posts():

    query_posts($query_string . ‘&YOUR QUERY_POST STRING’);

    if you wanted to simply get the default Loop after running a previous query_posts(), use:

    query_posts($query_string . ‘&orderby=date’);

  22. Gravatar unDesign patterns » Query_posts redux - If..Else Log September 7th, 2005 10:47 am

    […] Query_posts redux - If..Else Log […]

  23. Gravatar Klaus September 8th, 2005 7:15 am

    I am trying to pass a variable into the query_posts function, on my category template, in order to have the function showing only the posts of the current category. Like this:

    $titel=($cat);
    php query_posts('cat=$titel');

    query_posts does not accept variables as parameters. is there a way around, or do I have to build a category template for each category?

    UPDATE: I’m stupid but I managed to fixed it like this:


    $titel=($cat);
    $query= "cat=" . $titel. "&orderby=date&order=ASC";
    query_posts($query);

  24. Gravatar Mark November 8th, 2005 2:10 am

    Is it possible to run a “query_posts” function to get posts in a certain custom field? And then order them alpha-numerically by the values in those fields?

    I’m trying to hack WP to make a historical timeline, and I can’t just change the datestamp because I need to track events that go back well before 1970, or 1901 for that matter.

    I’m thinking of something like:
    query_posts(’orderby=date_year’);

    where date_year is the name of a custom field I’ve added.

    I’m afraid it won’t work because custom fields are metadata (or someththing like that) but any advice anyone can pass on I would appreciate.

    Thanks!

  25. Gravatar Adam Hopkinson November 16th, 2005 2:35 pm

    Great writeup. The problem i’m having is i need to display the excerpts of all the pages under the page being viewed. The only query_posts parameter that works on pages is page_id=x. I was hoping to use something like page_parent. I know this is primarily built for posts, but i’m using wordpress as a rudimentary cms. Any ideas?

    Many thanks!

  26. Gravatar mll November 20th, 2005 6:50 pm

    Hello there,

    Nice tut, thanks, but I still have a question.

    In my case, i want to use The_Loop twice on a page, but with *different* query_posts filters, the second time with no restriction (usual standard loop).

    But setting query_posts('’); in the second loop doesn’t actually reset the filter, and the 2nd loop displays the posts filtered in the first loop.

    Hope I was clear. Looking for your hints. :)

  27. Gravatar david December 14th, 2005 4:29 pm

    Hi,

    i wonder how to get the excluded list to take more than one section. I tried using if-else (heh) on php to exclude categories as stated on the codex, but couldnt get it to work with my current loop…

  28. Gravatar david December 14th, 2005 7:54 pm

    also, i didnt understood the fix for paged navigation

  29. Gravatar Macro Linz » links for 2006-01-02 January 3rd, 2006 6:02 am

    […] Query_posts redux - If..Else Log A good article on the undocumented parameters you can pass to the $wp_query function in the WordPress framework. Mainly for use in pages that need multiple “loops”. (tags: wordpress reference php tutorials codesnippet) […]

  30. Gravatar Emma February 10th, 2006 3:20 am

    Hello, I’m trying to create a front page like this:

    Cat 1: 1 article except + then 5 headline links
    Cat 2: 5 headline links
    Cat 2: 5 headline links etc…

    I previously used get_posts but this doesn’t seem to work with the new wordpress.

    Anyone know how to achieve this with query_posts? I’m totally confused!

  31. Gravatar Seoul Brother February 21st, 2006 1:50 am

    I’m late to this party but I’m using query_post(’cat=-20&showposts=5′) to for my “recent” post lists but I want to exclude the 2 most recent posts. I have my “reading” settings set to “days” instead of by “posts” as a work-around because my asides wouldn’t show in the sidebar properly.

    Any way to get query_post to exclude the most recent posts when you are set to show updates by x# of “days” instead of “posts”?

  32. Gravatar Wordpress tips and tricks » Binary Moon April 26th, 2006 12:09 pm

    […] Query_posts redux […]

  33. Gravatar Rob April 30th, 2006 9:16 pm

    Here’s a tricky one for you. I want to query a category within a page that has the same name as the page. The following example might help.

    query_posts(’category_name=the_title’):

    Any ideas on how to do this?

    Also this is a thread i recently started
    http://wordpress.org/support/topic/70841

    thx

  34. Gravatar My Enchanted Girl » Blog Archive » query_posts and !in_category, a blog and photoblog dream May 1st, 2006 6:26 am

    […] After reading through the posts at if…else [post_query redux](http://ifelse.co.uk/archives/2005/04/08/query_posts-redux/), [query_posts](http://ifelse.co.uk/archives/2005/03/31/query_posts/), and [One Post On Front Page](http://ifelse.co.uk/archives/2005/04/10/make-wp-show-only-one-post-on-the-front-page/) I was able to manipulate wordpress theme into a blog and photoblog theme like I’ve always wanted for IU. […]

  35. Gravatar Blogging Challenge: WordPress Treasure Hunt at MaxPower October 6th, 2006 9:18 pm

    […] query_posts — here is the answer […]

  36. Gravatar Glardkith « Lâmpada Azul November 5th, 2006 7:54 pm

    […] Phu Ly, de quem já usei por aqui 2 excelentes templates (além de inspiração, foi também referência, através do artigo Query_posts redux); […]

  37. Gravatar bigglesch March 12th, 2007 8:06 pm

    2 separate queries on one page.

    This may help some of the questions above.

    You can show either a page, then posts with a specific category, or 2 separate queries (results of one, followed by the other) etc. Variations easy.
    The key to this is you have to raise a separate query object.
    I wanted to do this because on the web site I am developing I have many static pages and a menu system. By creating the pages first, then creating a category with a matching id, I show any “Static” content, then followed by posts that relate to this page. Here is how:

    First there is the normal page loop:

    “>

    Read the rest of this page »’); ?>
    Pages: ‘, ‘’, ‘number’); ?>

    have_posts()) : $my_query->the_post(); ?>
    “>
    // (display stuff for each post here, same as above)

    Hope this helps someone

  38. Gravatar bigglesch March 12th, 2007 8:13 pm

    Oh, sorry for last post - of course the php stuff gets stripped when posting!
    so pseudo code follows
    page.php, normal part with
    if (have_posts()) : while (have_posts()) : the_post();
    (display the page post as normal)
    endwhile;
    endif;
    //my addition here!
    global $page_id; // get page used above
    //now make a new query, run a new loop
    $my_query = new WP_Query(”cat=”.$page_id.’&showposts=5′);
    while ($my_query->have_posts()) : $my_query->the_post();
    endwhile;

    that’s the basics, add checks for other conditions as you like.
    Obviously although I wanted a page at the top, you can display any normal stuff first, then customise for whatever to display underneath.

  39. Gravatar Simon September 14th, 2007 5:19 pm

    I know this posting is quite old. Anyway, I’ve a problem with query_post.

    I’m doing this at the top of index.php:

    Now I sadly get all Posts listed on the Starting Page and not just those from the category “startseite”. I also tried some other query strings, everytime i get all Posts listed…
    any idea where my problem is?

  40. Gravatar SEO & Web Design » Blog Archive » Mastering Your WordPress Theme Hacks and Techniques May 6th, 2008 7:29 am

    […] 1) Query_posts redux- A helpful tutorial to list some of the arguments that you can pass to the query_posts() function. […]

  41. Gravatar SEO & Web Design » Blog Archive » Mastering Your WordPress Theme Hacks and Techniques May 6th, 2008 7:29 am

    […] 1) Query_posts redux- A helpful tutorial to list some of the arguments that you can pass to the query_posts() function. […]