Exclude top-level pages from search results

I wonder if this will work for you:

function search_filter( $query )
{
    if( $query->is_search AND $query->is_main_query() )
    {
        // $query->set( 'post_parent__not_in', array( 0 ) ); // We comment this out here 
        $query->set( 'post_type', array( 'post', 'page' ) );
    }
    return $query;
}
add_action( 'pre_get_posts', 'search_filter' );

and

function wpse_120638( $where, $query ) 
{
    global $wpdb;

    if( $query->is_search AND $query->is_main_query() )
    {
            $from = "AND $wpdb->posts.post_type IN ('post', 'page')";
            $to   = "AND ( ( $wpdb->posts.post_parent NOT IN (0) 
                     AND $wpdb->posts.post_type IN ('page') ) 
                     OR $wpdb->posts.post_type IN ('post') ) ";

        $where = str_replace( $from, $to, $where );                                   
    }

    return $where;
}
add_filter( 'posts_where', 'wpse_120638', 10, 2 );

Leave a Comment