The following is a post by Jason Witt. Here Jason shares a method for doing something you might assume is pretty easy, but turns out to be a little bit more complicated than you might like. Fortunately with Jason’s code and examples, it can be easy.
Recently I had to make a custom WordPress query that listed post titles in alphabetical order. I started with a basic query like this.
$my_query = new WP_Query(array(
'post_type' => 'post',
'orderby' => 'title',
'order' => 'ASC'
));
My results were:

The results are technically in alphabetical order, but not how I wanted. I wanted the word “the” to be ignored if it was the title started with that, and to alphabetize by the next word instead. The desired order should look like this:

The “the” is called an Initial Article. You know: “A”, “An”, and “The”, the thing that sometimes gets put at the beginning of proper nouns. If you want to go international you can include “La” (Spanish) and “Les” (French). After a lot of searching and combing through WordPress Codex, I couldn’t find a native WordPress WP_Query
solution for ignoring an Initial Article.
What I did find were two very helpful filters that can let me achieve this, posts_fields
and posts_orderby
. With a little SQL know-how and PHP trickery. I was able to achieve the desired result.
Perhaps unsurprisingly, this is a pretty common need. Imagine a music library. Grouping all the bands that start with “The” under “T” would be needlessly confusing. Instead it’s like this:

How To Do It
Let me share with you how I did it, so you can use this in any WordPress project that requires you to alphabetize a WordPress query while ignoring Initial Articles.
In your `functions.php` file, add the following two functions.
function wpcf_create_temp_column($fields) {
global $wpdb;
$matches = 'The';
$has_the = " CASE
WHEN $wpdb->posts.post_title regexp( '^($matches)[[:space:]]' )
THEN trim(substr($wpdb->posts.post_title from 4))
ELSE $wpdb->posts.post_title
END AS title2";
if ($has_the) {
$fields .= ( preg_match( '/^(\s+)?,/', $has_the ) ) ? $has_the : ", $has_the";
}
return $fields;
}
function wpcf_sort_by_temp_column ($orderby) {
$custom_orderby = " UPPER(title2) ASC";
if ($custom_orderby) {
$orderby = $custom_orderby;
}
return $orderby;
}
This first function, wpcf_create_temp_column
, is going to create a virtual table column named “title2” at the time of the query. It populates the table column with the titles of your posts. If the title has the Initial Article “The”, it will be removed.
The second function, wpcf_sort_by_temp_column
, creates a new custom orderby
. It orders the posts by the virtual table column “title2” using the ASC
order.
To have these function work their magic on your queries, you simply add them to the filters I mentioned before.
add_filter('posts_fields', 'wpcf_create_temp_column');
add_filter('posts_orderby', 'wpcf_sort_by_temp_column');
Now your queries will order your post titles in alphabetical order while ignoring the Initial Article “The”. If you want to add additional Initial Articles to be ignored all you have to do is include them to the $matches
variable in the wpcf_create_temp_column
function, and separate them with a pipe character.
$matches = 'A|An|The|La|Les';
Now let’s say you have multiple WordPress queries that are being ordered by the title, but you don’t want to apply these filters to those queries. By adding the filters in your `functions.php` file they will affect every query on your site, so you probably don’t want that. Not to mention it may affect your site’s performance by using unnecessary filters. Here’s how you can apply those filters to specific queries.
First remove the add_filter
functions from your `functions.php` file. Then in your template file with desired query, put the add_filter
functions along with remove_filter
functions like this.
add_filter('posts_fields', 'wpcf_create_temp_column'); // Add the temporary column filter
add_filter('posts_orderby', 'wpcf_sort_by_temp_column'); // Add the custom order filter
$query = new WP_Query(array('post_type' => 'post')); // Your custom query
remove_filter('posts_fields','wpcf_create_temp_column'); // Remove the temporary column filter
remove_filter('posts_orderby', 'wpcf_sort_by_temp_column'); // Remove the temporary order filter
if (have_posts()) : while ($query->have_posts()) : $query->the_post(); // The query output
the_title();
echo '<br/>';
endwhile; endif; wp_reset_postdata();
In the above code, you’re adding the filters, executing the query, and then immediately removing the filters. By wrapping the query code in the filter your isolating those filter to that specific query.
Happy sorting!
Really useful post, thank you Chris for share Jason’s work.
If someone need to use Spanish/French full articles are:
$spanish_articles = ‘La|El|Las|Los|Una|Unas|Un|Unos’;
$french_articles = ‘La|Le|Les|Un|Une|Des’;
An issue in French: when a noun start with a vowel the article takes the form L’ for example:
L’Orchestre Philharmonique.
Interesting approach. Without using external libraries; is this really the most elegant approach to achieve this result? Without having implemented this on a local WP install, I’m wondering about the performance of this method.
Looked into doing this in PHP without a virtual table, came up with something that looks fairly ugly, but seems to work OK. Isn’t WordPress specific, but could probably sort the query results OK with some messing around.
I’ve used this on a live site for a client with no performance issues at all. The query I used it on is atually one of the fastest loading page on the site.
You’re approach is interesting and does seem to do the job, but I don’t think it falls into the ‘WordPress Way’. The filters I used in this are there just for these types of situations.
Instead of removing the filter, I would create a query variable that the 2 functions would check for.
I agree. That’s what I did for my version:
Implemented as a gist (untested, though): https://gist.github.com/mcaskill/d3ada21f9ff0800a6970
This will be terrible for performance. Once you get 10,000+ rows you’ll notice massive issues. Far better to hand this over to MySQL as part of the query, which you could do with CASE or IF statements.
Oh sure, if you’re querying 10,000+ rows you’ll have performance issues all around. That’s when you’ll use transients or Caching plugins like WP Super Cache.
What would you suggest to do?
If you really think that sorting is going to be faster in code than in the database then don’t go building anything complicated, please.
I’m not sure I understand where you’re coming from. The code in the article makes a custom MySQL query using the CASE method.
How would you make a MySQL query to use in template files without coding it?
Another option is to use
trim()
in the MySQL query, e.g. like...ORDER BY TRIM(LEADING 'a ' FROM TRIM(LEADING 'an ' FROM TRIM(LEADING 'the ' FROM LOWER(`post_title`))))
.A simple recursive function could generate that orderby clause.
Then, on the design side, apply CSS to the
$matches
to reduce opacity or change color to diminish the initial article and make it clear to the user that the list is alphabetized by the operative first word.Two words: The The ;)
Some more words: “Read the regexp more closely before replying” :)
Great share- Its funny how something so simple is like ignoring the “the” looks so complicated to actually implement.