WP Query where title begins with a specific letter

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.

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

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' );


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x