Querying for Posts and Custom Posts in WordPress

Learn two methods of querying Posts/Custom posts in WordPress.

Fetching Posts via get_posts()

There are many reasons why we may need to use the get_posts() function in WordPress. For example, we may want a subset of posts such as the 5 most commented posts, a few random posts, posts authored by a certain user, etc. Here is a quick example of how one might use get_posts() in a template to display some posts.

<?php 	$args = array( 		'posts_per_page' => 5,  // Limit to 5 posts 		'post_type' => 'post',  // Query for the default Post type 		'order_by' => 'post_date'  // Order by date posted 	); 	$last_five_posts = get_posts( $args );  	foreach ( $last_five_posts as $post ) : setup_postdata( $post ); ?> 		<h2> <?php the_title(); ?> </h2> 	<?php endforeach; 	wp_reset_postdata(); ?>

This simply gets the last five posts and outputs their title’s. Now lets say we have a Custom Post type named ‘products’, which has a Custom Taxonomy called ‘status’. We may want to find all products that have a status of ‘sold’ using the get_posts() function like so:

<?php 	$args = array( 		'posts_per_page' => -1,  // Get all posts 		'post_type' => 'products',  // The Custom Post Type we named 'products' 		'status' => 'sold'  // The Custom Taxonomy 'status' with value of 'sold' 	); 	$products_that_are_sold = get_posts( $args );  	foreach ( $products_that_are_sold as $product ) : setup_postdata( $product ); ?> 		<h2> <?php the_title(); ?> </h2> 	<?php endforeach; 	wp_reset_postdata(); ?>

The previous example finds all of our Custom Posts that are classified as ‘sold’ according to our Custom Taxonomy. The great thing about get_posts() is that it gives us control over what content we display.

Using the Loop/WordPress’s main query for handling queries

Another way of handling Post/Custom Post queries is to use WordPress’s already built in functionality. Much of the work is done behind the scenes for you, and in fact it is slightly more beneficial performance wise to utilize it. Before your template is even loaded, WordPress runs a query according to the request from the browser. Lets say your site has a custom taxonomy defined as ‘destination’ and you distinguish your posts by the destination of your trip. For example, routing to the following url www.yourwebsite.com/destination/columbia  would pull up a list of all your posts that have the taxonomy destination = columbia. We didn’t have to write a query, such as get_posts() above, because WordPress handles it for us behind the scenes. Take a look at the following image. This is how WordPress tries to decide what template to use depending on the query.

In the example I described above paragraph, we are routing through the path: Archive Page -> Custom Taxonomy Archive -> taxonomy-$taxonomy-$term.php -> taxonomy-$taxonomy.php -> taxonomy.php. This means that we can create a template defined in taxonomy-destination-columbia.php which describes exactly how this particular archive will apear. We can also define taxonomy-destination.php to define the layout of any destination (not just those labeled columbia). Rather than refining the query that WordPress has made for us in the template we need to use something called pre_get_posts. Take a look at the documentation for some good examples. Basically, pre_get_posts is a way of filtering or modifying the initial WordPress query before your template is loaded. This is how we get around running an additional query via get_posts(). Note: pre_get_posts is an action that must be placed in your themes function.php file.


  • get_posts() can handle all of our queries, but not always that efficiently.
  • Make use of the the Loop/main query whenever possible. This provides performance benefits by limiting the number of queries!
  • Use get_posts() to make an additional query aside from the ‘main loop’, or for more complicated scenarios.

We hope that this helps you select function useage in a collection/listing scenario for WordPress.