Site icon WebDevStudios

How to Search Everything Within Custom Post Types

Editor’s note: The following blog post was written in 2015. We can’t guarantee the accuracy of the code and presented solutions, but we’ve chosen to keep this blog post live for those who still find the information useful.
If you’re using Custom Post Types in your WordPress site, you might assume that your site search will display those posts along with the standard posts and pages in search results. However, WordPress actually has to be told to not only search custom post types, but a little extra work is needed to find in search all of the additional information that you might be storing in custom fields. Here’s a quick and easy way to search EVERYTHING within Custom Post Types.

I encountered this issue last month when I was working through QA tasks; the client was searching a specific keyword phrase and wondering why one of the most prominent pages on the site (that featured that phrase) wasn’t being returned in results. I saw that the page was an archive for the custom post type “Products” and added that to the array of post types available to the search query:

function wds_cpt_search( $query ) {

    // If we're on the search page, working with the main query, and searched something...
    if ( is_search() && $query->is_main_query() && $query->get( 's' ) ){

        // Include our product CPT.
        $query->set( 'post_type', array(
            'post', 
            'page', 
            'product', // Our Product CPT.
        ) );
    }
}
add_filter('pre_get_posts', 'wds_cpt_search');

But I still wasn’t seeing the page show up in results.

Looking at the Product post type, I saw that we were adding nearly all of our content to each Product via fields in a custom meta box. The keyword phrase I was looking for was specifically being entered into a WYSIWYG field via our CMB2 plugin. I checked and made sure the Product custom post type arguments for public and publicly_queryable were both set to true so it was available to the search query.

function wds_register_product_cpt() {

    // Register our product CPT.
    register_post_type( 'product', array(
        'public'             => true,
        'publicly_queryable' => true,
        'label'              => __( 'Products', 'textdomain' ),
    ) );
}
add_action( 'init', 'wds_register_product_cpt' );

Everything looked good there, so I set about building a custom search query that included the meta fields for each post being searched. By default, WordPress only includes post_title and post_content in its search query.

HANDY TIP: I tested two plugins, WP Search Everything and Relevanssi in the course of working on this issue and they both make it very easy to return all data from all post types in your site search if you want to skip the coding.

The Custom Field Parameters available to WP_Query via WP_Meta_Query are extremely handy (once I got over the impulse to just pop a SQL query into a function and call it good).

I just needed to return text from a single custom field, but the Codex page has a terrific breakdown of different ways to translate queries like “Show products where color=orange OR color=red AND size=small” into arguments you can pass to a new WP_Query object.

My query ended up being a little simpler than that but once I added a function to filter through pre_get_posts that used the following query, I got exactly the results I was looking for!

function wds_cpt_search( $query ) {

    // If we're on the search page, working with the main query, and someone searched for something...
    if ( is_search() && $query->is_main_query() && $query->get( 's' ) ) {

        // Add the CPT's to include in search.    
        $query->set( 'post_type', array( 
            'post', 
            'page', 
            'product' // Especially our product CPT.
        ) );

        // Search meta fields.
        $query->set( 'meta_query',  array(
                
            // Search our wysiwyg field for the field they searched for.
            array(
                'key'     => 'wysiwyg',
                'value'   => $query->get( 's' ),
                'compare' => 'LIKE',
            ),
        ) );
    }
}
add_action( 'pre_get_posts', 'wds_cpt_search' );

 

Exit mobile version