Search results ordered by custom post types are not grouped

This type of ordering is not available by default. You however have two basic options here

  • rewind_posts() -> Rerun the loop multiple times and use rewind_posts() to rewind the loop so you can rerun it again

EXAMPLE

if ( have_posts() ) {
    while( have_posts() ) {
        the_post();

        if ( $post->post_type == 'books' ) {
            // Output books posts
        }

    } // end first while loop

    rewind_posts(); // rewind loop so we can rerun it

    while( have_posts() ) { // Start second while loop
        the_post();

        if ( $post->post_type == 'cities' ) {
            // Output cities posts
        }

    } // end second while loop

    rewind_posts(); // rewind loop so we can rerun it

    // Run your third while loop for blog posts

} // End your if statement
  • The second method is to use usort and the the_posts filter to sort your posts accordingle before the loop is run.

EXAMPLE

(This goes into your functions.php)

add_filter( 'the_posts', function( $posts, $q ) 
{
    if(     $q->is_main_query()  // Targets the main query only
         && $q->is_search() // Only targets the search page
    ) {

        usort( $posts, function( $a, $b )
      {
            $post_types = array ( // Set your post type order here
                'books' => 1,
                'cities' => 2,
                'post' => 3
            );

            $posts = $post_types[$a->post_type] - $post_types[$b->post_type];

            if ($posts === 0) {
                //same post_type, compare by post_date.
                return $a->post_date < $b->post_date;
            }else{
                //different post_type, save to ignore the post_date.
                return $posts;
            }
        } );
    } 
    return $posts;  
}, 
10, 2 );

Leave a Comment