sift
John Reed

Written by John Reed

Share

WP_Query is a class that performs the bulk of the heavy lifting in WordPress. While most modifications to theme templates don’t require dealing with this class directly, The Loop, Conditional Tags, and many other features rely on it, so it’s important to understand the scope of this powerful set of functions.

Using the post__in Parameter for Precision Searches

As we begin to dig into the mother of all WordPress classes, let’s focus on the simple yet powerful post__in parameter, which accepts an array of IDs of posts to retrieve. For example:

$query = new WP_Query( array(
    'post__in' => array( 2, 5, 12, 14, 20 )
) );

Pass in some post IDs and get posts back. Easy! But when and how can we use this parameter dynamically?

Custom Queries and Enhancing The Loop

In advanced theme development, you may eventually need to write your own custom queries. While writing a modified loop to display the results of such a query is possible using a for each construct and the setup_postdata function, leaving your template code alone may be more efficient.

We recently developed advanced search functionality for one of our clients and found ourselves in this very situation. After wiring up our front-end search filters to our custom query, we didn’t want to have to rewrite our theme’s search results template. Using the pre_get_posts filter, we can execute a custom query and, in turn, alter the global $query object that is used in The Loop.

First, we add our filter and make sure we’re not altering any searches in the WordPress admin:

add_filter( 'pre_get_posts' , 'custom_advanced_search' );
function custom_advanced_search( $query ) {
    // don't alter search results in the admin!
    if( $query->is_admin ) return $query;
}

Then, we go ahead and execute our custom query (WHERE clause simplified for brevity):

    if( $query->is_search ) {
        global $wpdb;
        // custom query
        $query_string = "
            SELECT $wpdb->posts.*
            FROM $wpdb->posts
            WHERE $wpdb->posts.post_type = 'custom_post_type'
            GROUP BY $wpdb->posts.ID
        ";
        // execute custom query
        $results = $wpdb->get_results($query_string, OBJECT);
    }

Finally, we map our results to an array of IDs and update the post__in parameter via the set method:

add_filter( 'pre_get_posts' , 'custom_advanced_search' );
function custom_advanced_search( $query ) {
    // don't alter search results in the admin!
    if( $query->is_admin ) return $query;
    if( $query->is_search ) {
        global $wpdb;
        // custom query
        $query_string = "
            SELECT $wpdb->posts.*
            FROM $wpdb->posts
            WHERE $wpdb->posts.post_type = 'custom_post_type'
            GROUP BY $wpdb->posts.ID
        ";
        // execute custom query
        $results = $wpdb->get_results($query_string, OBJECT);
        // map results to a simple array of post IDs
        $posts = array_map( function($post) {
            return $post->ID;
        }, $results );
        // prevent empty array
        $posts = count($posts) ? $posts : array(-1);
        // only get posts from our custom query!
        $query->set( 'post__in', $posts );
    }
    return $query;
}
Note that if our custom query didn’t return any results, we set the $posts variable to an array containing -1; this is a simple workaround as passing an empty array to post__in currently returns the most recent posts (see Ticket #28099).

Since we have directly altered the global $query object, our search template will now automatically render the new results via The Loop without additional programming changes. (As a bonus, you can even set the orderby parameter to post__in to preserve the order passed via the post__in array!)

Why Custom WordPress Development Matters

This example is just one of the many ways we use custom queries to create functional WordPress sites tailored to specific business objectives. Whether boosting sales, improving content discoverability, or creating a unique user experience, custom development can ensure your website does exactly what you need.

Questions about how a tailored WordPress solution can work for you? Contact us today to explore what’s possible!

Photo by TUAN ANH TRAN on Unsplash

Tags
PHPWordPressWP_Query