A Better Way to Exclude Pages from Search Results

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 );
}
}
}

*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.