Rephrase question

I need to order posts inside the loop for my category car. What I need, if I visit the category page of car, I need all posts tagged BMW to display first, and then the other posts not tagged with the tag BMW

If my posts_per_page is set to display 10 posts, and I’m on page one, and three of the ten posts are tagged BMW, then these three posts must appear first, and the rest follows those three posts. When I click and go to page two, the same applies. If I have 5 out of these 10 posts tagged BMW, again they must appear first before the other 5 posts.

Is that possible?

3 Answers
3

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 Reply

Your email address will not be published. Required fields are marked *