While developing a client's multi-author WordPress site, our team found the default author list feature too basic. We previously shared a simple sidebar authors list, but for a dedicated contributors page packed with visuals and details, it fell short.
In this intermediate-level tutorial, drawn from real-world experience optimizing author pages for blogs, we'll show you how to create a dynamic contributors page. It displays authors with avatars (or user photos), names, websites, social links, and more—building trust and engagement for your readers.
First, create a custom page template (e.g., contributors.php) modeled after your theme's page.php.
Next, open your theme's functions.php file and add this function:
function contributors() {
global $wpdb;
$authors = $wpdb->get_results("SELECT ID, user_nicename FROM {$wpdb->users} ORDER BY display_name");
foreach ($authors as $author) {
echo '<li>';
echo '<a href="' . get_author_posts_url($author->ID) . '">';
echo get_avatar($author->ID);
echo '</a> ';
echo '<a href="' . get_author_posts_url($author->ID) . '">';
echo get_the_author_meta('display_name', $author->ID);
echo '</a></li>';
}
}This queries your users table and outputs a list with avatars and names. For the User Photo plugin, swap get_avatar($author->ID) with userphoto($author->ID). Easily extend it for URLs or bios using get_the_author_meta('field', $author->ID).
Add this CSS to your stylesheet for clean layout:
#authorlist li {
clear: left;
float: left;
margin: 0 0 5px 0;
}
#authorlist img.photo {
width: 40px;
height: 40px;
float: left;
}
#authorlist div.authname {
margin: 20px 0 0 10px;
float: left;
}In your template file, replace the content loop with:
<ul id="authorlist">
<?php contributors(); ?>
</ul>Perfect for multi-author blogs, this delivers a professional contributors page.
Here's our live example:

To match this richer design (excluding 'admin'), use this enhanced function:
function contributors() {
global $wpdb;
$authors = $wpdb->get_results("SELECT ID, user_nicename FROM {$wpdb->users} WHERE display_name != 'admin' ORDER BY display_name");
foreach ($authors as $author) {
echo '<li>';
echo '<a href="' . get_author_posts_url($author->ID) . '">';
echo get_avatar($author->ID);
echo '</a> ';
echo '<a href="' . get_author_posts_url($author->ID) . '">';
echo get_the_author_meta('display_name', $author->ID);
echo '</a><br />';
echo 'Website: <a href="' . get_the_author_meta('user_url', $author->ID) . '" target="_blank">';
echo get_the_author_meta('user_url', $author->ID);
echo '</a><br />';
echo 'On Twitter: <a href="' . get_the_author_meta('twitter', $author->ID) . '" target="_blank">';
echo get_the_author_meta('twitter', $author->ID);
echo '</a><br />';
echo '<a href="' . get_author_posts_url($author->ID) . '">Visit ';
echo get_the_author_meta('display_name', $author->ID);
echo '</a>'s Profile Page</li>';
}
}This leverages the User Photo plugin and a custom 'twitter' field (see our guide: How to show the author's Twitter and Facebook on the profile page).
Matching CSS:
#authorlist ul {
list-style: none;
width: 600px;
margin: 0;
padding: 0;
}
#authorlist li {
margin: 0 0 5px 0;
list-style: none;
height: 90px;
padding: 15px 0 15px 0;
border-bottom: 1px solid #ececec;
}
#authorlist img.photo {
width: 80px;
height: 80px;
float: left;
margin: 0 15px 0 0;
padding: 3px;
border: 1px solid #ececec;
}
#authorlist div.authname {
margin: 20px 0 0 10px;
}Adapt further as needed. Source of this function.