How to get posts from a custom post type

Updated by Tom Wells on

WordPress is a powerful, flexible and sometimes cumbersome content management system in 2020 and beyond. However, at some point in your development of WordPress themes or plugins, you'll come across the need to create and display a custom post type. For example, you might be creating a website for local restaurants in your town, so a "restaurant" custom post type makes sense. Having this custom post type will allow you to list the restaurants whilst maintaining the ability to have regular pages and posts.

If you're unsure how to create a custom post type in WordPress, I've created a gist to create the "restaurants" post type example we're using here.

Getting the posts from the custom post type

There are a handful of ways to retrieve posts from a custom post type in WordPress. However, I feel the best method is the get_posts() function. This function returns an array of the latest posts or posts that match specific criteria. For example, you can control not only the post type in the function arguments but also the number of posts to retrieve, the order, how the posts are ordered and much more. You can see the full list of arguments here.

Under the hood, this function is using WP_Query, so you're free to use WP_Query instead if you prefer.

For our use case, retrieving the posts from our "restaurants" post type would look like this:

index.php
$args = array(
  'numberposts' => 9,
  'post_type'   => 'restaurants'
);
$restaurants = get_posts( $args );

Here, we're obtaining nine of the latest restaurants posted to our WordPress website. The reason it's the latest restaurants is down to the default values in the arguments for get_posts(). You could change the arguments to order by title and alphabetically instead:

index.php
$args = array(
  'numberposts' => 9,
  'post_type'   => 'restaurants',
  'order'       => 'ASC',
  'orderby'     => 'title'
);
$restaurants = get_posts( $args );

Displaying the posts

Now we're successfully obtaining the restaurants posted to the custom post type; it's time to loop through the array and display them on the page:

index.php
<?php
$args = array(
  'numberposts' => 9,
  'post_type'   => 'restaurants',
  'order'       => 'ASC',
  'orderby'     => 'title'
);
$restaurants = get_posts( $args );

if ($restaurants) : ?>
  <ul>
    <?php foreach ( $restaurants as $restaurant ) : setup_postdata( $restaurant ); ?>
      <li><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></li>
    <?php endforeach; wp_reset_postdata(); ?>
  </ul>
<?php endif; ?>

To summarise, we're looping through our $restaurants array and employing the setup_postdata() function. setup_postdata() is a useful internal function for retrieving more of the post data than is available to get_posts() such as the_content() and although we're not utilising it thoroughly here, it's handy to know it exists!

First, we're checking there's data to loop through, and if so, we're adding a <ul> element to display the restaurants as a list. Then, in the end, we're closing the foreach loop, resetting the post data and ending the list. There's a lot more that can be achieved here, but having access to the whole post data with setup_postdata() you'll have the ability to customise how the restaurants are displayed to your liking.

Wrapping up

You've now learnt how to retrieve and display custom post types in WordPress. Well done! As you can see, it's not too daunting, and the get_posts() function ensures it's easy to follow and understand.

If you found this post useful, feel free to follow or tweet me on Twitter.