How can I add custom post types to the search in WordPress? (Instruction, 2023)

Marc Wagner, January 24, 2023

By default, custom post types are not included in WordPress search. But as always with WordPress, there is a hook that we use right now to expand/customize the search. In no time you have customized the search.

How to add Custom Post Types to WordPress Search with PHP #

The hook we need to extend the search is pre_get_posts. Below I’ll show you several snippets that will customize your search.

Code snippet for PHP 8 #

If your server already supports PHP 8, we recommend the following snippet to customize your search:

/**
 * This function extends the default WordPress WP_Query object 
 * to include an array of post types instead of the default 'post'
 * post type.
 */
function add_post_types_to_search_query(WP_Query $query): void{
  // Skip if this call has been triggered for an administrative interface page.
  if(is_admin()){
    return;
  }
  
  // Skip this call if this is not the search query and if this is not the main query.
  if(!$query->is_search() || !$query->is_main_query()){
    return;
  }
  
  // Define which post types should be searched
  $list_of_post_types = ['post', 'pages'];
  
  // Now - if we get to this point, this must be the search query which we will modify.
  $query->set('post_type', $list_of_post_types);
}
add_action('pre_get_posts', 'add_post_types_to_search_query', 10, 1);

Alternative: Code Snippet for PHP 7 #

You should only use this code if PHP 8 is not yet running on your server or your site is not compatible with PHP 8.

/**
 * This function extends the default WordPress WP_Query object 
 * to include an array of post types instead of the default 'post'
 * post type.
 */
function add_post_types_to_search_query($query){
  // Skip if this call has been triggered for an administrative interface page.
  if(is_admin()){
    return;
  }
  
  // Skip this call if this is not the search query and if this is not the main query.
  if(!$query->is_search() || !$query->is_main_query()){
    return;
  }
  
  // Define which post types should be searched. Replace/Extend by your post types.
  $list_of_post_types = array('post', 'pages');
  
  // Now - if we get to this point, this must be the search query which we will modify.
  $query->set('post_type', $list_of_post_types);
  
}
add_action('pre_get_posts', 'add_post_types_to_search_query', 10, 1);

Long-term easy to maintain thanks to OOP, code snippet #

Here’s an example of how you can map the whole thing with a class and namespaces if you want to keep maintenance low in the long run.

namespace My_Search{
  /**
   * This class extends the default WordPress WP_Query object
   * to include an array of post types instead of the default 'post'
   * post type.
   */
  class Search_Query_Post_Type_Modifier{
    /**
     * There should never be more than one object of this class therfor
     * we need to create a Singleton
     */
    private static ?Search_Query_Post_Type_Modifier $_instance = null;
    
    /**
     * This function will allow us to access the instance of this class
     */
    public static function get_instance(): Search_Query_Post_Type_Modifier{
        if(null === self::$_instance){
           self::$_instance = new Search_Query_Post_Type_Modifier();
        }
      
      	return self::$_instance;
    }
    
    /**
     * Private constructor to disable multiple instances of this object.
     */
    private function __construct(){
     	add_action('pre_get_posts', [$this, 'add_post_types_to_query']);
    }
    
    /**
     * Add the post types to the search query
     */
    public function add_post_types_to_query(WP_Query $query): void{
  		// Skip if this call has been triggered for an administrative interface page.
  		if(is_admin()){
           	return;
        }

        // Skip this call if this is not the search query and if this is not the main query.
        if(!$query->is_search() || !$query->is_main_query()){
          	return;
        }

        // Define which post types should be searched
        $list_of_post_types = ['post', 'pages'];

        // Now - if we get to this point, this must be the search query which we will modify.
        $query->set('post_type', $list_of_post_types);
  	}
  }
  
  /**
   * Instantiate the object
   */
  Search_Query_Post_Type_Modifier::get_instance();
}

As few lines of code as possible: #

This version is meant to simply use as few lines of code as possible :)

add_action('pre_get_posts', function(WP_Query $query){
   if(!is_admin() && $query->is_search() && $query->is_main_query()){
     $query->set('post_type', ['post','page']);
   }
}, 10, 1);
Avatar of Marc Wagner
Marc Wagner

Hi Marc here. I'm the founder of Forge12 Interactive and have been passionate about building websites, online stores, applications and SaaS solutions for businesses for over 20 years. Before founding the company, I already worked in publicly listed companies and acquired all kinds of knowledge. Now I want to pass this knowledge on to my customers.

Similar Topics

Comments

Leave A Comment

Title