WordPress: How To Properly Add Your Custom Post Type To Your Homepage

Hello first time visitor!

Does your WordPress plugin create a custom post type? Read on.

Sometimes you’ll want your custom post type to be displayed in the home page along with other posts. This is what we had to do with Namaste! LMS.  We wanted the courses user create to get included in the homepage.

The official Codex page offers some solution here. And it’s not good. The problems with solution are two:

  • It misses ‘nav_menu_item’ type which will cause problems with some designs
  • More important: it assumes you are the only one who wants to add their post type to the main query.

There are several other forum threads and blogposts which suggest nearly the same with a few extra configurations.

All these solutions may work if you work on a custom site but not if you want to release a plugin to the public. I quickly realized that when working on Daskal using the same advice and figured out Namaste!’s custom post type setting overrides Daskal’s custom post type setting in the main query. And this is to be expected because the solutions suggest that you simply have to hardcode all the required custom post types.

You shouldn’t do this.

The Proper Way To Handle This

You should add your custom post type to the existing post types. If there are other ones added in the main query, you shouldn’t be overwriting them.

So, here’s the code you need:

add_action( 'pre_get_posts', 'your_pre_get_posts_function' );

function your_pre_get_posts_function() {
   if ( (is_home() or is_archive()) and $query->is_main_query() ) {
       $post_types = @$query->query_vars['post_type'];

	// empty, so we'll have to create post_type setting			
	if(empty($post_types)) {
	   if(is_home()) $post_types = array('post', 'page', 
              'nav_menu_item', 'your_custom_post_type');
	   else $post_types = array('post', 'nav_menu_item', 
	// not empty, so let's just add it
	if(!empty($post_types) and is_array($post_types)) {				
	   $post_types[] = 'your_custom_post_type';
	   $query->set( 'post_type', $post_types );
   return $query;

That’s it. In the code above we check whether the use is on homepage or archive page, and whether it’s the main query.
Then we are getting the current post types. If they are empty, we’ll just create the array like most guides are suggesting.
However if it is not empty, we’ll add it to the array instead of assuming our plugin is the only one that wants their post type in the home page.

Comments welcome.

Leave a Reply