WordPress Snippet: List Authors/Contributors

We were playing around with Brian (@bkmacdaddy) today on a WordPress blog with a few over 50 authors, then bumped into an issue where we had to output a list of all contributors. It’s quite easy at first sight, and functions such as wp_list_authors are quite good at it, but not good enough.

The main issue was that the authors had to be paged and sorted by their names. Moreover, each entry had to contain the contributor’s avatar, Twitter profile, short biography and the website URL. And the other funny part is that we had to exclude the admin user and all users with no posts, which turned out to have quite a simple solution.

After a few hours struggling, we finally came to a solution that is quite interesting, and most importantly, seems to work. There may be a little drawback when retrieving the whole users list, and a direct query to the SQL database with a few JOINs and a LIMIT could have solved that, but it’s not the case if we have some caching plugin turned on. So, here’s the snippet:

// Use this to sort authors by display name
function sort_authors($a, $b)
{
	return strcmp($a['display_name'], $b['display_name']);
}

// Output a list of contributors
function contributors() {
	$authors = array();

	// Get all blog users
	$blogusers = get_users();
	foreach ($blogusers as $bloguser)
	{
		// Fetch
		$user = get_userdata($bloguser->user_id);
		$numposts = get_usernumposts($user->ID);

		// Skip if admin or has no posts
		if ($user->user_login == 'admin' || $numposts < 1) continue;
		$authors[] = (array) $user;
	}

	// Sort the authors by display name
	usort($authors, 'sort_authors');

	// Get the current page
	$paged = get_query_var('paged');
	if (!$paged) $paged = 1;

	// We'll return these at a later stage
	$current_page = $paged;
	$total_pages = ceil(count($authors) / 10);

	// Calculate the starting and ending points
	// Assuming we'll be showing 10 authors per page
	$start = ($paged - 1) * 10;
	$end = $paged * 10;
	if ($end > count($authors)) $end = count($authors);

	// Loop through the authors
	for ($i = $start; $i < $end; $i++)
	{
		$author = $authors[$i];

		// Gather data and meta
		$nicename = $author['user_nicename'];
		$display_name = $author['display_name'];
		$avatar = get_avatar($author['ID']);
		$author_profile_url = get_bloginfo('url') . '/author/' . $nicename . '/';
		$website = get_usermeta($author['ID'], 'user_url');
		$twitter = get_usermeta($author['ID'], 'twitter');
		$bio = $author['description'];

		// Hide if empty
		$twitter = strlen($twitter) > 0 ? 'Twitter: <a href="http://twitter.com/' . $twitter . '" target="_blank">@' . $twitter . '</a><br />' : '';
		$website = strlen($website) > 0 ? 'Website: <a href="' . $website . '" target="_blank">Visit</a><br />' : '';
		$bio = strlen($bio) > 0 ? 'Bio: ' . substr($bio, 0, 50) . '... <a href="' . $author_profile_url . '">Read more</a><br />' : '';

		// Output the list
		print <<<HTML
			<li>
				<a href="{$author_profile_url}">{$avatar}</a>
				<div>
					<a href="{$author_profile_url}">{$display_name}</a><br />
					{$bio}
					{$website}
					{$twitter}
					<a href="{$author_profile_url}">Visit {$display_name}'s Profile Page</a>
				</div>
			</li>
HTML;
	}

	// Return an array containing current and total pages
	// These values could be used to output pagination
	return array(
		'current_page' => $current_page,
		'total_pages' => $total_pages
	);
}

The snippet consists of two functions. The first function is simply a helper function that is passed to the usort function when we need to reorder the contributors in alphabetical order. A simple strcmp is used as the sorting algorithm.

The second function is quite complex. We use the get_users_of_blog function, which unfortunately is not described in the Codex. It returns all the users of the current blog (in our case, there’s only one blog). Looping through all the users, we eliminate the admin, and those who haven’t got any published posts, then form an array of authors. This array is then sorted, and finally, after some pagination tweaks and calculations, we output the list of contributors, depending on the current page (uses get_query_var).

After all that messy stuff, we return our two variables which will help build the pagination UI. And we’re done. Use this in your functions.php and call contributors() in a page template or something ;)

Cheers, and don’t forget to share this post!

About the author

Konstantin Kovshenin

WordPress Core Contributor, ex-Automattician, public speaker and consultant, enjoying life in Moscow. I blog about tech, WordPress and DevOps.

28 comments

  • Can you explain more how to put a 'paged' into query var to make the pagination works? If we simple paste the contributors() function in a page template, I think the 'paged' variable always is 1.

    • Rilwis, good question. As I stated in the article, the function uses get_query_var, this means that to get to page two, you simply add ?paged=2 to your query (or /page/2/ if your permalinks are turned on). Hope that explains it.

  • Zdraz woutje Mister K. Thanks for this great tip. Haven't quite understood how to make pagination workin' nor appearin' on my template though. A bit of complementary explanation would be greatly appreciated as well as in regards to CSS. Spaciba. Frederic

  • Hi! This is a great script but I'd like to know how to make some modifications to it. How do I show the full Bio? I also want the avatar to link to the author's entries filter and not their main webpage. How would I do that?

    Help would be greatly apperciated!

    Thanks!

    • Meghan, if you read the code step-by-step, you'll be able to change links, bios and all the rest. It's quite straightforward ..

  • How in the world can I get this to sort by post count? Since it's not in the actual array, is there any way I can sort this by post count?? I have been trying for hours now.

  • the problem is that I couldn't find post count in the array. I eventually just added it to the array and then used the sort and reversed the order. It;s working now, but I'm not sure if it will get slow with a lot of users.

  • Hey, this is great I'm a designer and was trying to figure out something like this for an online magazine I'm working on. This might sound totally stupid but I've wrapper your snippet in php tags and for some reason it isn't displaying any content when I know their should be something displayed. Any advice?

    • Modified the code at line 20
      // Skip if admin or has no posts
      if ($user->user_login == 'admin' || $numposts user_login == 'admin' || $numposts wp_user_level < 2) continue;

      This will skip the normal subscribers :)

    • Sorry error in previous one.

      Modified the code at line 20

      if ($user->user_login == ‘admin’ || $numposts user_login == ‘admin’ || $numposts wp_user_level < 2) continue;

      This will skip the normal subscribers :)

  • Hello kovshenin,

    Im trying to implement your code with my own to use the pagination feature but Im not having any success.

    Im using the $blogusers = get_users($args); foreach ($blogusers as $user) { … }

    Im getting the exact results that I want but I need to add a pagination feature to the list.

    Using the base functions, how can I add pagination to my results?

    thank you!

    • You'll have to do it manually Gary, I don't think there's a native all-purpose pagination function in WordPress, at least not of which I know. Most are done for WP_Query.