stop wordpress search showing a custom post type stop wordpress search showing a custom post type wordpress wordpress

stop wordpress search showing a custom post type


The answer here depends on whether you're creating the CPT via your own code, or if another plugin is creating the CPT. See this link for a great explanation of both approaches:

http://www.webtipblog.com/exclude-custom-post-type-search-wordpress/

The basic gist is this:

If you're creating your own CPT, you can add an argument to the register_post_type() call of 'exclude_from_search' => true

If another plugin / theme is creating the CPT, you need to set this exclude_from_search variable later on, as part of a filter to the CPT, as such:

// functions.phpadd_action( 'init', 'update_my_custom_type', 99 );function update_my_custom_type() {    global $wp_post_types;    if ( post_type_exists( 'staticcontent' ) ) {        // exclude from search results        $wp_post_types['staticcontent']->exclude_from_search = true;    }}


I don think accepted answer is correct. exclude_from_search prevents all $query = new WP_Query from returning results.

The core says:

...retrieves any type except revisions and types with 'exclude_from_search' set to TRUE)

This is a common problem and mixup with the front end search results page v.s. search posts in the database.

Presenting content using custom queries on front end, needs exclude_from_search = false or use another approach and get the content by id directly.

You need to filter the search front end mechanism instead. This is a true Exclude Post Types From Search, without manually re-build "known" types:

function entex_fn_remove_post_type_from_search_results($query){    /* check is front end main loop content */    if(is_admin() || !$query->is_main_query()) return;    /* check is search result query */    if($query->is_search()){        $post_type_to_remove = 'staticcontent';        /* get all searchable post types */        $searchable_post_types = get_post_types(array('exclude_from_search' => false));        /* make sure you got the proper results, and that your post type is in the results */        if(is_array($searchable_post_types) && in_array($post_type_to_remove, $searchable_post_types)){            /* remove the post type from the array */            unset( $searchable_post_types[ $post_type_to_remove ] );            /* set the query to the remaining searchable post types */            $query->set('post_type', $searchable_post_types);        }    }}add_action('pre_get_posts', 'entex_fn_remove_post_type_from_search_results');

And remark $post_type_to_remove = 'staticcontent'; can be changed to fit any other post type.

Please make a comment if Im missing something here, I cant find another way to prevent post type scenarios like this, showing content by query but hide from search/ direct access to front end users.


First of all, the answer by Jonas Lundman is correct and should be the accepted answer.

The exclude_from_search parameter does work incorrectly - it excludes the post type from other queries as well.

There is a ticket on WP issue tracking system, but they have closed it as wontfix because they cannot fix this without breaking the backwards compatibility. See this ticket and this one for more details.

I've added additional checks to the solution proposed by Jonas Lundman, because:

  • in real setups there can be other plugins trying to modify the search query, so simply replacing the post_type may cause unexpected results.
  • I think it's more flexible to use an array of post types to exclude.
add_action('pre_get_posts', 'remove_my_cpt_from_search_results');function remove_my_cpt_from_search_results($query) {    if (is_admin() || !$query->is_main_query() || !$query->is_search()) {        return $query;    }    // can exclude multiple post types, for ex. array('staticcontent', 'cpt2', 'cpt3')    $post_types_to_exclude = array('staticcontent');    if ($query->get('post_type')) {        $query_post_types = $query->get('post_type');        if (is_string($query_post_types)) {            $query_post_types = explode(',', $query_post_types);        }    } else {        $query_post_types = get_post_types(array('exclude_from_search' => false));    }    if (sizeof(array_intersect($query_post_types, $post_types_to_exclude))) {        $query->set('post_type', array_diff($query_post_types, $post_types_to_exclude));    }    return $query;}