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?
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.