Recently I’ve had to group the search results of a website by its post type, and I couldn’t use Relevanssi due to infrastructure reasons. This was a major problem to me due to the lack of documentation or tutorials over the internet.
The solution is quite simple, tho:
On functions.php insert the following code lines:
if( !is_admin() && isset($_GET['s']) && $_GET['s'])
{
add_filter( 'posts_orderby', 'separate_result_types', 1 );
}
function separate_result_types($query)
{
global $wpdb;
$query = "$wpdb->posts.post_type, $wpdb->posts.post_date DESC";
return $query;
}
Once wordpress doesn’t support a post_type orderby on the WP_Query queryvars, you have to add a hook that will be activated when a query is about to run. This will order the posts for its post_type, and then for the post_date (which is the default ordination for wordpress) so you won’t lose the order on other loops.
Then, on your search.php (or whatever loop file you’re using), use the loop like this one:
<?php if(have_posts()): ?>
<?php
//This will store the last post type in a var, and every time it changes, it'll print the post type separator.
$lastType = false;
$counter = 0;
while (have_posts()): the_post();
if ($lastType != $post->post_type):
$counter++;
$lastType = $post->post_type;
switch ($post->post_type)
{
case 'post':
$postTypeTitle = "Blog";
break;
case 'page':
$postTypeTitle = "Pages";
break;
case 'event':
$postTypeTitle = "Events";
break;
case 'project':
$postTypeTitle = "Projects";
break;
case 'newsletter':
$postTypeTitle = "Newsletters";
break;
}
echo '<h2>' . $postTypeTitle . '</h2><hr/>';
endif;
?>
<h3><a href="<?=get_permalink()?>"><?php the_title(); ?></a></h3>
<?php the_excerpt(); ?>
<?php endwhile; ?>
<?php else: ?>
<p>No results found.</p>
<?php endif; ?>
Enjoy!

