How to extend the where clause in WordPress WP_Query

Lately i was building a website and i found myself needing to modify WordPress’ WP_Query class. More specifically, i needed to find all posts that the title would contain a specific keyword.

So my first attempt with WP_Query was:

$my_query = new WP_Query(
    array(
        'post_type' => 'post',
        'post_status' => 'publish',
        'posts_per_page' => 20,
        'orderby' => array('menu_order' => 'ASC', 'date' => 'DESC'),
        'update_post_meta_cache' => false,
        'update_post_term_cache' => false,
        's' => $search_key
    )
);

where $search_key contains the keyword i need each time. However, the above query searches the post content as well and not only the post title. I only need to search the post_title.

So i found out that WordPress offers a hook called posts_where. Oh how I love WordPress!

So, to extend the where clause of the WP_Query, you need to add the following lines in your functions.php file:

add_filter( 'posts_where', 'extend_wp_query_where', 10, 2 );
function extend_wp_query_where( $where, $wp_query ) {
    if ( $extend_where = $wp_query->get( 'extend_where' ) ) {
        $where .= " AND " . $extend_where;
    }
    return $where;
}

Then, to call WP_Query, using the extended clause we just built:

$my_query = new WP_Query( array(
    'post_type' => 'post',
    'post_status' => 'publish',
    'posts_per_page' => 20,
    'orderby' => array('menu_order' => 'ASC', 'date' => 'DESC'),
    'update_post_meta_cache' => false,
    'update_post_term_cache' => false,
    'extend_where' => "(post_title like '%".$search_key."%')"
));

This way you can use the extend_where to customize your WP_Query.

Another example would be:

$my_query = new WP_Query( array(
    'post_type' => 'post',
    'post_status' => 'publish',
    'posts_per_page' => 20,
    'orderby' => array('menu_order' => 'ASC', 'date' => 'DESC'),
    'update_post_meta_cache' => false,
    'update_post_term_cache' => false,
    'extend_where' => "(post_title like '%".$search_key."%' or post_title like '%".$search_key2."%')"
));