Sort posts by tags in category pages

There really is no sane way to accomplish this, specially if you have posts that are assigned to more than one tag (which is almost always the case). What is very sure, you have you work cut out for you.

Here are some thought and ideas you can persue:

POSTS WITH MULTIPLE TERMS

If posts have more than one tag (or any term for that matter) assigned to them, it means that there are more than one relationship to another post or set of posts, and grouping those together will either: (a). Be impossible without duplication, or (b). Be possible, with duplication of posts.

The terms (tags in this case) assigned to a post from a specific taxonomy (post_tag in this case) is ordered in a specific way when more than one term exists. Simply grabbing the first term might not always be the term you would want to use.

Sorting tags from get_the_tags() (or the more generic get_the_terms()) would require additional PHP sorting to sort the returned array of tag object to suite your needs, or you would want to use a function like wp_get_post_tags() to do the sorting via SQL, but it would require an extra db call.

If you want to sort by the first tag only, then it is quite easy if you sorted the tag array to suite or needs. I’ll post example code later

WORKAROUND

If you have posts with multiple tags, you will need to find a specific unique relationship between posts, and according to that, either:

  • assign a custom field with a sortable value to a set of posts and then use pre_get_posts to sort your category pages according to custom field value

  • create a specific taxonomy for this, and then assign a special term to a set of posts and then use the the_posts filter, which I will post, to sort the returned array of posts

If you do not mind post duplication, you have a look at this post, this was however done for custom fields, so you would need to break it down and modify it to work with tags, but in essence, the principle by building a multidimentional array, flatten it later and then return a sorted array with duplicate posts remains the same

POSTS WITH SINGLE TAGS

If you have posts assigned to one tag only (or you are happy to sort by first tag only), it is quite easy to sort the posts accordingly by using the the_posts filter. You can try the following then (UNTESTED and very basic)

add_filter( 'the_posts', function ( $posts, \WP_Query $q )
{
    // Make sure we only target the main query on category pages
    if (    !is_admin()
         && $q->is_main_query()
         && $q->is_category()
    ) {
        // Use usort to sort the posts
        usort( $posts, function( $a, $b )
        {
            return strcasecmp( 
                get_the_tags( $a->ID )[0]->name, 
                get_the_tags( $b->ID )[0]->name 
            );
        });
    }
}, 10, 2 );

Leave a Comment