While working on a potential new plugin idea I tried to find the most future-proof and inclusive method to remove a built-in post type from the search results. In my case, I am actually trying to remove posts from the search results, but that lead me to an often Google-d method to exclude pages from search results.
The common solution is to set the query variable to ‘post’, however this limits the search results specifically to posts and nothing else. By default WordPress searches posts, pages and attachments. However, there are plenty of other plugins that create post types that you might want to have searchable (eCommerce ‘product’ post types, for instance).
This little snippet allows you to selectively exclude post types from search results (like pages, in this example), without monkeying around with any others. It’s great because you can set it and forget it – install and create other post types without worry that they will suddenly not show up on your search results*.
<?php | |
/** | |
* Modify query to remove a post type from search results, but keep all others | |
* | |
* @author Joshua David Nelson, [email protected] | |
* @license http://www.gnu.org/licenses/gpl-2.0.html GPLv2+ | |
*/ | |
add_action( 'pre_get_posts', 'jdn_modify_query' ); | |
function jdn_modify_query( $query ) { | |
// First, make sure this isn't the admin and is the main query, otherwise bail | |
if( is_admin() || ! $query->is_main_query() ) | |
return; | |
// If this is a search result query | |
if( $query->is_search() ) { | |
// Gather all searchable post types | |
$in_search_post_types = get_post_types( array( 'exclude_from_search' => false ) ); | |
// The post type you're removing, in this example 'page' | |
$post_type_to_remove = 'page'; | |
// Make sure you got the proper results, and that your post type is in the results | |
if( is_array( $in_search_post_types ) && in_array( $post_type_to_remove, $in_search_post_types ) ) { | |
// Remove the post type from the array | |
unset( $in_search_post_types[ $post_type_to_remove ] ); | |
// set the query to the remaining searchable post types | |
$query->set( 'post_type', $in_search_post_types ); | |
} | |
} | |
} |
<?php | |
/** | |
* Modify query to remove a post type from search results, but keep all others | |
* | |
* @author Joshua David Nelson, [email protected] | |
* @license http://www.gnu.org/licenses/gpl-2.0.html GPLv2+ | |
*/ | |
add_action( 'pre_get_posts', 'jdn_modify_query' ); | |
function jdn_modify_query( $query ) { | |
// First, make sure this isn't the admin and is the main query, otherwise bail | |
if( is_admin() || ! $query->is_main_query() ) | |
return; | |
// If this is a search result query | |
if( $query->is_search() ) { | |
// Gather all searchable post types | |
$in_search_post_types = get_post_types( array( 'exclude_from_search' => false ) ); | |
// Make sure you got the proper results, otherwise bail. | |
if ( ! is_array( $in_search_post_types ) ) { | |
return; | |
} | |
// The post types you're removing, in this example 'page' and 'post' | |
$post_types_to_remove = array( 'post', 'page' ); | |
// loop through each one and remove it from the searchable post types, if it's in there. | |
foreach ( $post_types_to_remove as $post_type ) { | |
// Confirm if the post type is in the results | |
if( in_array( $post_type, $in_search_post_types ) ) { | |
// Remove the post type from the array | |
unset( $in_search_post_types[ $post_type ] ); | |
} | |
} | |
// set the query to the remaining searchable post types | |
$query->set( 'post_type', $in_search_post_types ); | |
} | |
} |
*It should be noted that if you are creating a custom post type and you don’t want to have it in the search results, don’t use this method. Just set the exclude_from_search
to true when you register the post type.