How to Add Custom Post Types to Your Home Page and Feeds

Custom Post Types in WordPress Loop and FeedCustom post types are a powerful way to extend the functionality of your website, creating a more personal experience for the viewer, and also the admin. But when you create a new custom post type, it is not automatically added to the site’s main loop. If that custom post type is one you plan to feature on the homepage of you’ll need to modify your theme’s functions.php file.

Luckily, that’s done with just a few lines of code.

Adding Custom Post Type to your Home Page in WordPress

function custom_conference_in_home_loop( $query ) {
 if ( is_home() && $query->is_main_query() )
 $query->set( 'post_type', array( 'post', 'your_custom_post_type_here') );
 return $query;
 }
 add_filter( 'pre_get_posts', 'custom_conference_in_home_loop' );

Let’s break that down.

The first line creates a function and names it ‘custom_conference_in_home_loop, passing it a variable $query, which will be modified during the function.

The second line tests if we’re on the home page and if the query is the main query, and if those conditions are true, it executes line 3; setting the post type contained in the main query to an array containing the standard post type ‘post’, and your custom post type. The query is returned in line 4, the function closed in line 5, and finally, in line 6 we hook into the main query with ‘pre_get_posts’, which runs before template and theme functions are called. This is preferable to creating a new query or simply querying posts in a custom function, and helps speed up page load time, especially on sites with larger databases.

Basically, this function is telling WordPress before the main query is built to include our new custom post type in the home page loop, which, in-turn, adds it to the main feed, which can be accessed easily via:

http://example.com/feed

Line 2 is very important – checking if you are working with the main query. If that is left out, the hook will affect other items like sidebars, menus, even admin functions. You can also see the ‘Display Posts Shortcode’ plugin by Bill Erickson for a way to do this on posts and pages without using hard code.

 

Separate Feeds for Custom Post Types

But what if you don’t want to give your readers the ability to grab a feed just for that custom post type, and not necessarily all post types that you might have included with the above, or similar filter.
Continuing with the event conference example above, our readers want to grab a year-specific feed and get automatic updates pertaining only to that specific year.

This presents an easy solution because it doesn’t require any code at all, just a link which takes the following form:

http://example.com/feed/?post_type[]=yourposttype1

or to create a feed with multiple post types use:

http://example.com/feed/?post_type[]=yourposttype1&post_type[]=yourposttype2

Filter the Custom Post Type Feed by Custom Taxonomy

If you created a custom post type chances are you’ve created custom taxonomies to go with it. If you want to give readers an even more granular selection of feeds, you can filter that custom post type feed further by drilling down into specific taxonomies within that post type.

Again, we continue with our conference example and now assume we offer the following hierarchical taxonomies:

  • Conference 2012 – Custom posts relating only to the 2012 conference
  • Conference 2011 – Custom posts relating only to the 2011 conference
  • Conference 2010 – You get the idea by now…

You could offer a feed showing only the current year’s conference updates by adding the taxonomy name at the end of the feed url:

http://example.com/feed/?post_type[]=yourposttype&yourposttype_categoryslug=actual_category

Our custom post type ‘conference-updates’ has a custom taxonomy with a slug of  “conference-year” which was set when we registered the custom taxonomy. If this were a real site, we would use something like this for the actual feed:

http://example.com/feed/?post_type[]=conference-updates&conference-year=2012

That link can be displayed with a custom box on your site, in a widget, as a text link, or wherever you can paste html. For more information on editing custom post types and creating custom feeds, checkout these two resources:


Comments (8)

    • Jonny,

      I came across that plugin but haven’t used it yet myself. I took a look at the code just a few minutes ago and it looks pretty lean, which is good for a plugin. I’ll try it out in my next site.

      I’m a fan of pre_get_posts because it loads before the main query and theme functions.

  1. I’ve tried adding this code and for some reason it’s not populating the custom post types into my main feed. I’m using the plugin “Types” and have created 2 custom post types. Is there a reason those shouldn’t be working?

    • I’m not familiar with that plugin or how it works, so I can’t comment on whether it might be causing the issues.
      I’ve used the WPMUDEV plugin, custompress, which works great. And also Custom Post Type UI, which works great.

      I don’t mean to push you off, I just don’t know that plugin, and without seeing how it registers post types, I can’t comment on whether it might be the issue.

      If none of the above works, I would say this: try turning the plugin off and adding the custom post type using code in functions.php. Follow the instructions here for how to do that:http://codex.wordpress.org/Function_Reference/register_post_type

      Hope that helps.

  2. Hey Craig it’s a really great snippet that you shared.
    I did try to improve on it by dynamically getting all of the post types and I end up with a working functions.php file but I get the following php notice when in debug mode :
    Notice: Undefined variable: args in /www/wp-content/themes/sparkling-child/functions.php on line 22

    function custom_conference_in_home_loop( $query ) {
    if ( is_home() && $query->is_main_query() )
    $args = array(
    'public' => true,
    '_builtin' => false
    );
    $output = 'names'; // names or objects, note names is the default
    $operator = 'and'; // 'and' or 'or'
    $post_types = get_post_types( $args, $output, $operator );
    $query->set( 'post_type', $post_types );
    return $query;
    }
    add_filter( 'pre_get_posts', 'custom_conference_in_home_loop' );

    Like I said your code works great and fast but since I have 12 custom post types I was trying to get them all at once into one variable. Any help greatly appreciated.

  3. Sorry I forgot to use the pre tag

    Notice: Undefined variable: args in /home/dealgoyoks/www/wp-content/themes/sparkling-child/functions.php on line 22

    And the code in functions.php is :

    function custom_conference_in_home_loop( $query ) {
    if ( is_home() && $query->is_main_query() )
    $args = array(
    ‘public’ => true,
    ‘_builtin’ => false
    );
    $output = ‘names'; // names or objects, note names is the default
    $operator = ‘and'; // ‘and’ or ‘or’
    $post_types = get_post_types( $args, $output, $operator );
    $query->set( ‘post_type’, $post_types );
    return $query;
    }
    add_filter( ‘pre_get_posts’, ‘custom_conference_in_home_loop’ );

Participate