Display all posts in category, with specific tag posts at top

Here’s a simplified combination of both @PieterGoosen and @ialocin fine answers by using the loop_start hook:

add_action( 'loop_start', function( $q ) {
    if( $q->is_main_query() && $q->is_category( 'car' ) )
        usort( $q->posts, function( $a, $b ){
            return -1 * has_tag( 'bmw', $a ) + 1 * has_tag( 'bmw', $b );            });
}, 10, 2 );

We could also use the same method for the the_posts filter.

Update:

To sort posts on the home page, by the first category name, we can try for example:

add_action( 'loop_start', function( $q ) {
    if( $q->is_main_query() && $q->is_home() )
        usort( $q->posts, function( $a, $b ){
            return strcasecmp( 
                get_the_category( $a->ID )[0]->name, 
                get_the_category( $b->ID )[0]->name 
            );
        });
}, 10, 2 );

where we use strcasecmp for case-insensitive string comparison.

Leave a Comment