Post Loop By Category

Alex Bluesummers asked on a WordPress list:

How do I order posts in the loop by whether or not it is in a category, then by date?

Suppose I have 10 posts, of which 5 are in the category “Sports” and 5 are in the category “Blog News”. Both “Sports” and “Blog News” posts are mixed together chronologically. “Sports” and “Blog News” posts share other categories and tags. I want both types of posts to be present in the loop regardless of whether it’s the front page or category archive view, but ordered by “Sports” and “blog news” and then by date. How is this most elegantly accomplished?

I can think of two ways, both have their advantages and drawbacks. Here’s what I offered in response:

You’ll probably do best by running multiple loops. That way you know exactly where each category of posts begins and ends and you can choose how many you want in each section. You’ll also be able to avoid burying a category because you had a run of posts in another category.

On the other hand, maybe that’s what you want, or maybe you have other ideas. In that case…

MySQL’s ORDER BY FIELD( $fieldname, ...list of matching entries in the order you want them...) syntax my be what you need. You’d have to join the term relationships table, then order by term_taxonomy_id (or go all the way and join the other tables to order by category name).

If you go that route, the posts_join and posts_orderby filters will be your friends. You’d probably want to hook a function to the pre_get_posts action that checks that the request is for the front page and then applies the filters. You should probably also apply a hook the to remove the filters on loop_end or something like that so they don’t disrupt other queries.