Jan
28
2009

Using WP_Query to Fetch Posts in WordPress

by   |  Posted in Tutorials  |  22 comments

I was just putting together a WordPress widget for a client and I came across a small road block. I was using <?php query_post(); ?> to set the loop to act the way I needed it to but when the widget loaded up in the left sidebar, it caused some issues when going to a category page. The problem was the query I initialized in the sidebar was carrying over to the main section. I couldn’t figure out what to do until I stumbled up the wp_query function.

It works in a similar way to query_post but you need to do a few minor things to get it to work properly.

<?php
$featuredPosts = new WP_Query();
$featuredPosts->query('showposts=5&cat=3');
while ($featuredPosts->have_posts()) : $featuredPosts->the_post(); ?>
<h1><a href="<?php the_permalink() ?>"><?php the_title(); ?></a></h1>
<div class="meta">
By <?php the_author() ?>
</div>
<div class="storycontent">
<?php the_excerpt(); ?>
</div>
<?php endwhile; ?>

First you need to setup the query.

$featuredPosts = new WP_Query();
$featuredPosts->query('showposts=5&cat=3');

Then you need to setup the loop.

while ($featuredPosts->have_posts()) : $featuredPosts->the_post(); ?>
     (stuff goes here)
<?php endwhile; ?>

So in the end it looks something like this.

<?php
$featuredPosts = new WP_Query();
$featuredPosts->query('showposts=5&cat=3');
while ($featuredPosts->have_posts()) : $featuredPosts->the_post(); ?>
<h1><a href="<?php the_permalink() ?>"><?php the_title(); ?></a></h1>
<div class="meta">
By <?php the_author() ?>
</div>
<div class="storycontent">
<?php the_excerpt(); ?>
</div>
<?php endwhile; ?>

What this will do is get 5 posts from category 3 and list them, without interfering with other loops or queries on your site.

About the author:

A freelance web developer living in Montreal who spends most of his time writing for this site and building Premium themes for WordPress. You can find him on Twitter @bavotasan.

Site5 Affiliate Link
If you liked this, please share it.

Tags: , , , , , , , , , , , , , , , , , , , ,

Short URL: http://bit.ly/d1v73p

Discussion 22 Comments

  1. Alex on June 15, 2009 at 3:45 am

    I tried the code above on a test website and it works..but when i tried on the real thing…it doesn’t. I mean on the home page nothing is displayed(title and post in sidebar) but when i access a post or category it shows what is should have shown. Any ideas why?

    • c.bavota on June 18, 2009 at 1:36 pm

      Hmm. Do you have an if statement wrapping the code?

  2. Facundo on August 19, 2009 at 1:17 am

    Sos un groso! Hacia mucho que venia buscando esto y no lo encontraba.
    Funciona de 10, muchas gracias!

  3. TechSlam on October 20, 2009 at 3:18 pm

    I have a question.
    Inmy WP theme, i have a home page with a sidebar.

    the home page displays latest 5 posts of a category named “Features” and on the same page the sidebar displays the latest 5 titles of another category named “news” and both these have their category name as heading. The problem is I am not able to get the proper category name to show up, it shows the “news” category name on both the sections. i am using query_posts(). I did not try wp_query, but after looking into your code, i feel that it will give me the same issue. I mean, can’t I use the_category before the while loop to fetch the respective category name???

    • c.bavota on October 21, 2009 at 10:52 am

      query_posts() should only be used once. That is the main loop that usually is where you a calling your main list of posts. wp_query should be used for every other other query. the_category() always has to be in the loop unless you are on a category page, then it can be outside. How is it suppose to know what category to call if you have not created a loop calling posts for that category. If you don’t want to have it within the loop, you can always use:

      <?php echo get_the_category(Cat_ID); ?>

      Replace Cat_ID with the category ID.

  4. Robert Stanson on November 14, 2009 at 7:23 pm

    Useful information there

  5. Danno on March 29, 2010 at 9:33 pm

    Elegant solution to a common problem. I like it.

  6. Ryan on April 20, 2010 at 3:21 am

    I always stumble upon your blog whenever I am searching for a WordPress coding solution. :) Thanks!

  7. andy on April 27, 2010 at 6:51 am

    thanks man! that came through in the clutch, was simple to follow, and worked! woot!

  8. Gokul on May 21, 2010 at 7:13 am

    Ya it’s good but the_content()s’ more option doesn’t work ,
    Please give any solution

  9. Israel Morales on August 5, 2010 at 10:09 am

    Obrigado!!

    Thank you just what i need!!

  10. Fin on August 22, 2010 at 10:52 am

    Thanks a million…

  11. Spain holiday blog on October 2, 2010 at 9:19 pm

    How can I extract the latest 5 posts from our wp blog and display them on an asp page. Any suggestions?

  12. Sale Generators on February 2, 2011 at 5:29 am

    i try it to put on the single post but it wont show up the category i want to display . please help. thanks

  13. Philip on February 9, 2011 at 10:28 am

    How can I get the query to pull by category name instead of category number?

    • c.bavota on February 9, 2011 at 11:33 am

      The only option that is close is category_name but it actually uses the category slug and not the actual name.

    • Philip on February 9, 2011 at 1:20 pm

      That works exactly the way I needed it, Thanks very much for responding to my question. I have a lot of categories so this makes it a lot easier for me to manage.

  14. Joel Sellnau on February 28, 2011 at 1:32 pm

    That worked great….ty.

  15. Cas on March 11, 2011 at 10:30 am

    Maybe you can help me out here. I have a custom post-type “my-custom-post-type” and I’ve set up a custom query for it in a separate loop file like this:

    // set up a new query
    $my_custom_query = new WP_Query( array(
    										'post_type' 	=&gt; 'my-custom-post-type',
    										'order'		=&gt; 'ASC',
    										'post_status'	=&gt; 'future'
    										));

    Now I’m working on a widget plugin where I need to filter the posts of my query and check if a particular ID is in the query. In the plugin file it says something like this:

    global $wp_query;
    $post_id = $wp_query-&gt;get_queried_object_id();
    $show = isset($instance['page-'.$post_id]) ? ($instance['page-'.$post_id]) : false;
     
    if (!$show and isset($instance['other_ids']) and !empty($instance['other_ids'])){
    	// do stuff
    }

    My problem here is: Calling global $wp_query only checks within the default query of WordPress. To make the plugin run through my custom query, it would have to read like

    global $my_custom_query;
    $post_id = $my_custom_query-&gt;get_queried_object_id();
    // ...etc..

    wouldn’t it? But $my_custom_query is unique variable name from my particular template file. It won’t work in other cases but mine, not with other custom queries.

    So, how can make this thing scalable? Do you know about a way to do something like

    // 1. Somehow check if there are any custom queries set up in my theme
    // 2. Get each custom query by its var name, like $my_custom_query
    // 3. Do a foreach loop for each of those custom queries with something like this inside: 
    $post_id = $my_custom_query-&gt;get_queried_object_id();
    $show = isset($instance['page-'.$post_id]) ? ($instance['page-'.$post_id]) : false;
    // ...etc...

    The ultimate task would be to make the plugin actually run through ALL post-IDs, no matter if they belong to posts, pages or custom post-types.

    Any ideas highly appreciated!

    • Cas on March 11, 2011 at 10:34 am

      Sorry for the >s, forgot to escape.

    • Cas on March 11, 2011 at 10:34 am

      Funny, now it worked. ;-)

  16. Mike Carter on May 2, 2011 at 8:02 pm

    Really clear instructions in above post, by the way. I’m just getting into queries.

    My question is, what I only want to show the content of the posts on a page and not the whole post. For example:
    Post 1 content is: some stuff
    Post 2 content is: some other stuff
    Post 3 content is: some other stuff

    Can I set this up to show the “stuffs” without having a list of three Posts? Just the “stuff” in them?

    Thanks — I know this is a bit crazy and maybe impossible.