By default, WordPress displays posts on archive pages in reverse chronological order. While this works perfectly for a standard blog where the newest content is most relevant, it is often suboptimal for directories, glossaries, or staff listings. If you need to sort WordPress archive pages by name in ascending order, you need to tell WordPress to modify its default query logic.
In this guide, we will explore the most efficient ways to achieve alphabetical sorting. We will focus on the professional standard using the pre_get_posts hook, as well as alternative methods for specific use cases like category-specific glossaries. By the end of this tutorial, you will have a deep understanding of how to manipulate the WordPress query to suit your site's organizational needs.
Understanding the WordPress Query Lifecycle
Before diving into the code, it is important to understand why we choose certain methods over others. When a visitor lands on an archive page, WordPress has already run a "Main Query" to fetch the posts based on the URL. If you modify the sorting within the template file (like archive.php) using a new WP_Query, you are essentially forcing the server to run a second, redundant query, which can slow down your site.
To keep your site performant, the best practice is to intercept the primary query before it is executed. This is where the pre_get_posts hook becomes your most powerful tool.
Method 1: Using the pre_get_posts Hook (Recommended)
The pre_get_posts action hook allows developers to modify the query variables object after it is created but before the actual database query is run. This ensures that the "Main Query" returns the posts in the correct order from the start.
You should place the following code in your theme's functions.php file:
add_action( 'pre_get_posts', 'my_change_sort_order');
function my_change_sort_order($query){
// Check if we are in the admin area or if this is not the main query
if ( is_admin() || ! $query->is_main_query() ) {
return;
}
// Target archive pages specifically
if( is_archive() ):
// If you wanted it for the archive of a custom post type use: is_post_type_archive( 'your_post_type' )
// Set the order to ASC (Ascending) or DESC (Descending)
$query->set( 'order', 'ASC' );
// Set the orderby parameter to 'title'
$query->set( 'orderby', 'title' );
endif;
}
Why This Works
In the code above, we use $query->set() to change two specific parameters:
1. orderby: We set this to title. In WordPress, title refers to the post title you see in the editor, while name refers to the post slug. For alphabetical sorting, title is usually what you want.
2. order: We set this to ASC (Ascending, A-Z). If you wanted Z-A, you would use DESC.
By checking is_archive(), we ensure that this logic only applies to category, tag, and date archives. If you want to be even more specific, you can use conditional tags like is_category() or is_post_type_archive().
Method 2: Sorting Specific Categories via Custom Loops
Sometimes, you don't want to change the global behavior of all archives. For instance, you might have a specific category called "Glossary" that needs alphabetical sorting, while your "News" category should remain chronological.
In this scenario, you can modify the logic directly within your template or a specialized template part. Here is how you can use get_posts to fetch and display posts alphabetically for a specific category:
<?php
// We check if we are on the 'Glossary' category page
if ( is_category('Glossary') ) {
$args = array(
'posts_per_page' => -1, // Retrieve all posts
'orderby' => 'title',
'order' => 'ASC'
);
$glossaryposts = get_posts( $args );
}
// Loop through the results
if ( !empty($glossaryposts) ) :
foreach( $glossaryposts as $post ) : setup_postdata( $post );
?>
<li><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></li>
<?php
endforeach;
wp_reset_postdata(); // Important: reset the global $post object
endif;
?>
Pros and Cons of Method 2
- Pros: Highly specific; does not affect other parts of the site; easy to implement for one-off lists.
- Cons: Less efficient than
pre_get_postsbecause it often runs in addition to the main query; breaks standard pagination unless handled manually.
Troubleshooting Common Sorting Issues
If your posts are still not sorting correctly after applying these changes, check the following common pitfalls:
1. The Main Query Check
Always ensure you are using $query->is_main_query(). Without this check, your code might accidentally change the sorting of navigation menus, sidebar widgets, or admin dashboard lists, leading to unexpected layout breaks.
2. Plugin Conflicts
Some SEO or "Post Types Order" plugins use their own hooks to force a specific sort order. If your code isn't working, try disabling plugins that manage post ordering or increase the priority of your hook:
add_action( 'pre_get_posts', 'my_change_sort_order', 20 ); // Higher number = later execution
3. Title vs. Name
Remember that orderby => 'title' sorts by the human-readable title. If you use orderby => 'name', WordPress will sort by the URL slug (e.g., my-post-title). While often similar, they can differ if you have manually edited your permalinks.
Frequently Asked Questions
Can I sort by name and then by date as a fallback?
Yes! WordPress allows you to pass an array to the orderby parameter. For example: $query->set( 'orderby', array( 'title' => 'ASC', 'date' => 'DESC' ) );. This will sort alphabetically, and if two posts have the same title, the newest one will appear first.
Does this work for Custom Post Types (CPT)?
Absolutely. Simply replace is_archive() with is_post_type_archive( 'your_cpt_slug' ) in the pre_get_posts function. This is the standard way to handle directories or portfolio archives.
Will this affect my SEO?
Changing the order of posts can change how search engines crawl your site. Alphabetical sorting is excellent for user experience on reference-heavy sites, which can indirectly improve SEO metrics like bounce rate and time-on-page.
Wrapping Up
Sorting your WordPress archives by name is a straightforward process when you use the pre_get_posts hook. It is the most performant and "WordPress-way" to handle query modifications. While custom loops with get_posts have their place for specific sections like glossaries, sticking to the main query logic ensures your site remains fast and compatible with standard pagination.
Whether you are building a glossary, a directory, or just want a more organized archive, these snippets provide the flexibility you need to customize your WordPress site's behavior. Always remember to test your changes in a staging environment to ensure your conditional tags are targeting exactly the pages you intend.