I want to search for posts with WP_Query() and select only posts that begin with a specific letter. I found a bunch of old posts with filters that were pre-4.4, but since 4.4 there is a title search added to the WP_Query function.
$q = new WP_Query( array('post_type'=>'post','title'=>'This Song Title') );
This will return only exact matches of posts with the title “This Song Title”.
What I would like to do is return all posts that start with, in this example, the letter ‘T’
I also found this post, which was never really answered. It’s the accepted answer, but I don’t see how it answers the question at all.
How to limit search to first letter of title?
Other query features like comment and meta searches have a ‘compare’ for adding LIKE% to queries, but title does not seem to.
It’s not possible with WP_Query
directly out of the box, but by using the posts_where
filter to look for a custom argument on WP_Query
, it is possible to add this functionality.
Assuming starts_with
is the name of the argument we want to use, we can filter posts_where
to add a WHERE
clause limiting results to those that begin with the given value if starts_with
has been set on the query:
function wpse_298888_posts_where( $where, $query ) {
global $wpdb;
$starts_with = esc_sql( $query->get( 'starts_with' ) );
if ( $starts_with ) {
$where .= " AND $wpdb->posts.post_title LIKE '$starts_with%'";
}
return $where;
}
add_filter( 'posts_where', 'wpse_298888_posts_where', 10, 2 );
With this filter added, we can query posts like this:
$query = new WP_Query( array(
'starts_with' => 'M',
) );
That will return all posts beginning with “M”.
If you want to be able to filter the main query, you can also use this argument in pre_get_posts
:
function wpse_298888_pre_get_posts( $query ) {
if ( $query->is_main_query() ) {
$query->set( 'starts_with', 'M' );
}
}
add_action( 'pre_get_posts', 'wpse_298888_pre_get_posts' );