Here is how you can group your post listing based on their terms. First you need to add the following code to your functions.php
// join the term_taxonomy table so we can get the term id with the post
add_filter( 'posts_join_paged', 'wpse39380_posts_join', 10, 2 );
function wpse39380_posts_join( $join, $query ) {
// you need to add your check here so not all queries are modified
if ( $query->is_archive && $query->tax_query ) {
$join .= " LEFT JOIN wp_term_taxonomy ON wp_term_relationships.term_taxonomy_id=wp_term_taxonomy.term_taxonomy_id";
}
return $join;
}
// order the posts by term_id
add_filter('posts_orderby', 'wpse39380_orderby_terms', 10, 2 );
function wpse39380_orderby_terms( $orderby, $query ) {
// you need to add your check here so not all queries are modified
if ( $query->is_archive && $query->tax_query ) {
return ' wp_term_taxonomy.term_id ';
}
return $orderby;
}
// add the term_id to select fields
add_filter( 'posts_fields', 'wpse39380_posts_field', 10, 2 );
function wpse39380_posts_field( $fields, $query ) {
// you need to add your check here so not all queries are modified
if ( $query->is_archive && $query->tax_query ) {
$fields .= ", wp_term_taxonomy.term_id";
return $fields;
}
return $fields;
}
Now your custom loop will look like following:
$args = array(
'post_per_page' => '-1',
'tax_query' => array(
array(
'taxonomy' => 'fruit',
'field' => 'slug',
'terms' => array('apple','orange','grape')
)
)
);
$query = new WP_Query( $args );
$current_term = null; // to keep track of term
while($query->have_posts()) : $query->the_post();
global $post;
// if we have current_term set
// and current_term not equal to the current post term
if ( $current_term && $current_term != $post->term_id ) {
echo '</div>';
$current_term = null;
}
// if current_term is null then either its the first iteration
// or the last term posts have been displayed
if ( $current_term === null ) {
$current_term = $post->term_id;
$term = get_term( ( int ) $current_term, 'fruit' );
echo "<div id='$term->name'>";
echo "<h2>$term->name</h2>";
}
the_title();
echo '<br />';
endwhile;
if ( $current_term ) {
echo '</div>';
}