How to group the loop posts in a particular by author?

I have links going to category pages on a WordPress blog. These category pages show all the posts that are in that category and sub-categories. I want to group these lists by the authors.

I guess need to modify category.php to first list all the authors which have posts in that particular category and then run WP_Query multiple times for each author. The second part is okay, but I can’t figure out how to get the list of authors of only those posts in this category.

2 Answers
2

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;

Leave a Comment