Function Friday #20: add custom post types into the main loop
Every Friday, I’m sharing code snippets that I use to customize WordPress. Feedback/suggestions are always welcome! For more information, check out the first post in the series.
If you love custom post types as much as I do, you may have wished for a “Posts Page” setting for the custom post type archive. Or maybe you want to separate Posts from (for example) Press Releases on the back end, but they should display mixed in together on the front end.
In my case, I wanted to give the client the option to change where the archive for their custom post type was located rather than hard-coding it into the theme. Because this site wasn’t going to use Posts in the standard way, I figured the existing “Posts page” setting would work well.
The code
// Use custom post type in main loop
function drollic_add_projects_to_loop( $query ) {
if ( ! is_admin() && $query->is_main_query() ) {
// Posts page
if ( $query->is_home() ) {
$query->set( 'post_type', array( 'projects' ) );
}
}
return $query;
}
add_action( 'pre_get_posts', 'drollic_add_projects_to_loop' );
The first line makes sure this function won’t change the query in the WordPress admin area, and that it’s actually the main query that you’re modifying. Then it checks whether you’re currently viewing the Posts page (is_home will be true on that page only).
Finally, it alters the query to only display posts with the post type “projects”. Because this takes an array, you could use the same code to add a custom post type in amongst your normal posts instead:
$query->set( 'post_type', array( 'posts', 'press-releases' ) );
Altering the query like this is possible because pre_get_posts fires before the query is actually executed. I’ve used it before, to change what displays when someone submits an empty search on your site. It can do a bunch of useful stuff, so I recommend reading through the hook’s Codex page for more ideas!
As always, remember to name your function with a unique prefix (like I’ve done here with drollic_) to avoid conflicts with WordPress core and plugin functions.
Where does it go?
If you’re creating custom post types in your theme, this function belongs in your theme’s functions file too. If you’re doing it via a functionality plugin, this code should go in the plugin. There’s more information on where to put your code in the first Function Friday post.
Resources
- is_admin in the WordPress Code Reference
- is_main_query in the WordPress Codex
- is_home in the WordPress Code Reference
- pre_get_posts in the WordPress Codex
Leave a Reply