I don't think you need to get the list of authors in a given category or use a bunch of individual WP_Query
's, you just need to order posts by author and check to see when the author changes.
Two parts to this. One to modify the loop on category pages to order by author. You can hook into pre_get_posts
to do this.
<?php
add_action('pre_get_posts', 'wpse56168_order_author');
/**
* Change the order of posts only on the category pages.
*
* @param WP_Query $q The current WP_Query object
* @author Christopher Davis <http://christopherdavis.me>
* @return void
*/
function wpse56168_order_author($q)
{
if($q->is_main_query() && $q->is_category())
{
$q->set('orderby', 'author');
$q->set('order', 'ASC'); // alphabetical, ascending
}
}
Now to get a list of authors.
Since WP_Query
fetches all posts at once -- it doesn't stream data in -- you can array_map
the posts to get the Author IDs out and create your list. Because you altered the order of post above, the authors should come out in order. Wrapping this up in a function might be a good idea:
<?php
/**
* Extract the authors from a WP_Query object.
*
* @param WP_Query $q
* @return array An array of WP_User objects.
*/
function wpse56168_extract_authors(WP_Query $q)
{
// this is PHP 5.3+, you'll have to use a named function with PHP < 5.3
$authors = array_map(function($p) {
return isset($p->post_author) ? $p->post_author : 0;
}, $q->posts);
return get_users(array(
'include' => array_unique($authors),
));
}
Then you can use something like this in your category.php
template to generate the list.
<ul>
<?php foreach(wpse56168_extract_authors($wp_query) as $author): ?>
<li><?php echo esc_html($author->display_name); ?></li>
<?php endforeach; ?>
</ul>
Grouping the post by authors should just be a matter of compare the previous posts author with the current posts author.
Example:
<?php
$old_author = 0;
while(have_posts()): the_post();
?>
<?php if($post->post_author != $old_author): ?>
<h2><?php the_author(); ?></h2>
<?php endif; ?>
// display post here
<?php
$old_author = $post->post_author;
endwhile;