This article will guide you through the process of creating a front-end
page in WordPress that lists your authors. We’ll discuss why you would
want to do this, we’ll introduce the
WP_User_Query class, and then we’ll put it it all together.
User Engagement And WordPress
At its core, WordPress is a rock-solid publishing platform. With a
beautiful and easy to use interface, and support for custom post types
and post formats, publishers have the flexibility to do what they do
best:
write content.
However, WordPress is lacking in social interaction between content
authors and readers. BuddyPress is trying to solve this, but I believe
it’s going in the wrong direction by trying to be a full-fledged social
network.
A big phrase in the publishing world is “user engagement.” This is
about getting readers to spend more time on the website, actively
searching for content and even generating their own. While one could
write a few books on the subject, here are a few things a WordPress
publisher can do:
- Create a daily or weekly newsletter, with top stories from selected categories;
- Provide an editorial-driven open forum in which editors propose themes, stories and questions and readers comment on them;
- Continue the discussion of articles on social platforms;
- Encourage users to submit articles and images for contests;
- Highlight your authors.
Listing Authors, And Why It’s A Good Thing
If you’re a publisher, your authors are your biggest asset. They are
the content creators. Their writing gets consumed by millions of people
all over the world.
Showcasing them exposes them for what they really are: authorities.
Your authors will thank you for acknowledging them, and readers will get
to see the human face behind the technology.
Coding The Perfect Author Listing
Here are the things we want to achieve with our page:
- Build it as a WordPress plugin so that we can reuse it more easily;
- Display the name, biography, number of posts and latest published post of all authors;
- Paginate the listing if we have many authors;
- Make the listing searchable.
Introducing WP_User_Query And get_users
The
WP_User_Query class allows us to query the user database.
Besides returning an array of users,
WP_User_Query returns general information about the query and, most importantly, the total number of users (for pagination).
One can use
WP_User_Query by passing a series of arguments and listing the output.
01 | $my_authors = new WP_User_Query( |
03 | 'blog_id' => $GLOBALS['blog_id'], |
15 | 'count_total' => true, |
We’ll focus on only a few arguments, rather than go through all of them:
role
This is the user’s role. In our example, we’ll query for author.
offset
The first n users to be skipped in the returned array.
number
Limit the total number of users returned.
We also have the
get_users class, which (like
WP_User_Query) returns a number of users based on the parameters set.
The important difference between the two is that
get_users only returns an array of users and their meta data, whereas
WP_User_Query returns extra information such as the
total number of users (which is useful when it comes time to paginate).
Simple User Listing Using get_users()
Before moving on with the full user listing, including pagination and search, let’s see
get_users in action.
If all you need is a simple list of authors, then you could just use
wp_list_authors, like so:
1 | wp_list_authors('show_fullname=1&optioncount=1&orderby=post_count&order=DESC&number=3'); |
Creating A Plugin And Shortcode With A Bit More Functionality
A simple and straightforward way to build our user listing would be
to create a shortcode that we could include on any page we like. Housing
this type of functionality in a plugin is ideal, so that we don’t have
to worry about migrating it when we change the theme.
Let’s keep it simple. Our entire plugin will consist of just one file:
simple-user-listing.php.
011 | function sul_user_listing($atts, $content = null) { |
014 | extract(shortcode_atts(array( |
019 | $role = sanitize_text_field($role); |
020 | $number = sanitize_text_field($number); |
027 | $search = ( isset($_GET["as"]) ) ? sanitize_text_field($_GET["as"]) : false ; |
030 | $page = (get_query_var('paged')) ? get_query_var('paged') : 1; |
033 | $offset = ($page - 1) * $number; |
037 | $my_users = new WP_User_Query( |
040 | 'search' => '*' . $search . '*' |
044 | $my_users = new WP_User_Query( |
047 | 'offset' => $offset , |
054 | $total_authors = $my_users->total_users; |
057 | $total_pages = intval($total_authors / $number) + 1; |
060 | $authors = $my_users->get_results(); |
063 | <div class="author-search"> |
064 | <h2>Search authors by name</h2> |
065 | <form method="get" id="sul-searchform" action="<?php the_permalink() ?>"> |
066 | <label for="as" class="assistive-text">Search</label> |
067 | <input type="text" class="field" name="as" id="sul-s" placeholder="Search Authors" /> |
068 | <input type="submit" class="submit" name="submit" id="sul-searchsubmit" value="Search Authors" /> |
072 | <h2 >Search Results for: <em><?php echo $search; ?></em></h2> |
073 | <a href="<?php the_permalink(); ?>">Back To Author Listing</a> |
076 | </div><!-- .author-search --> |
078 | <?php if (!empty($authors)) { ?> |
079 | <ul class="author-list"> |
082 | foreach($authors as $author){ |
083 | $author_info = get_userdata($author->ID); |
086 | <?php echo get_avatar( $author->ID, 90 ); ?> |
087 | <h2><a href="<?php echo get_author_posts_url($author->ID); ?>"><?php echo $author_info->display_name; ?></a> - <?php echo count_user_posts( $author->ID ); ?> posts</h2> |
088 | <p><?php echo $author_info->description; ?></p> |
089 | <?php $latest_post = new WP_Query( "author=$author->ID&post_count=1" ); |
090 | if (!empty($latest_post->post)){ ?> |
091 | <p><strong>Latest Article:</strong> |
092 | <a href="<?php echo get_permalink($latest_post->post->ID) ?>"> |
093 | <?php echo get_the_title($latest_post->post->ID) ;?> |
096 | <p><a href="<?php echo get_author_posts_url($author->ID); ?> ">Read <?php echo $author_info->display_name; ?> posts</a></p> |
101 | </ul> <!-- .author-list --> |
103 | <h2>No authors found</h2> |
106 | <nav id="nav-single" style="clear:both; float:none; margin-top:20px;"> |
107 | <h3 class="assistive-text">Post navigation</h3> |
108 | <?php if ($page != 1) { ?> |
109 | <span class="nav-previous"><a rel="prev" href="<?php the_permalink() ?>page/<?php echo $page - 1; ?>/"><span class="meta-nav">←</span> Previous</a></span> |
112 | <?php if ($page < $total_pages ) { ?> |
113 | <span class="nav-next"><a rel="next" href="<?php the_permalink() ?>page/<?php echo $page + 1; ?>/">Next <span class="meta-nav">→</span></a></span> |
119 | $output = ob_get_contents(); |
123 | if (is_page()) return $output; |
128 | add_shortcode('userlisting', 'sul_user_listing'); |
Breaking Down The Code
The top of our plugin’s main PHP file must contain the standard
header of information. This header tells WordPress that our plugin
exists, and it adds it to the plugin management screen so that it can be
activated, loaded and run.
Creating a Shortcode
Adding a new shortcode in WordPress is rather easy. We find the function that returns the desired output (in our case,
sul_user_listing), and then we add it using the
add_shortcode WordPress function.
1 | function sul_user_listing($atts, $content = null) { |
4 | add_shortcode('userlisting', 'sul_user_listing'); |
Extracting Our Shortcode Arguments
We want to be able to list users based on their roles and to control
how many users are displayed on the page. We do this through shortcode
arguments. We’ll add the shortcode to our theme in this way:
[userlisting role="author" number="15"]. This will allow us to reuse the plugin to list our subscribers as well.
To do this, we need to use shortcode arguments:
1 | extract(shortcode_atts(array( |
The
extract function imports variables into our function from an array. The WordPress function
shortcode_atts basically returns an array with our arguments; and we’ll set up some defaults in case none are found.
Note that the
role default is an empty string, which would list all users regardless of their role.
Shortcodes Should Never Echo Stuff Out
The return value of a shortcode handler function gets inserted into
the post content’s output in place of the shortcode. You should use
return and not
echo;
anything that is echoed will be outputted to the browser but will
probably appear above everything else. You would also probably get
“headers already sent” type of errors.
For simplicity, we’re buffering the output through
ob_start(), so we put everything into an object and return it once we’re done.
Setting Up Our Variables
Now we can start building our listing of authors. First, we need to set up a few variables:
$search
This takes the GET parameter as if it exists.
$page
The get_query_var for the pagination. This already exists in WordPress.
$offset
Calculate the offset (i.e. how many users to skip when paginating).
$total_authors
Get the total number of authors.
$total_pages
Calculate the total number of pages for the pagination.
The Query
We actually have two queries: the default listing and the search results.
03 | $my_users = new WP_User_Query( |
06 | 'search' => '*' . $search . '*' |
10 | $my_users = new WP_User_Query( |
WP_User_Query->total_users and WP_User_Query->get_results
WP_User_Query provides us with two useful functions, among others:
total_users
Returns the total number of authors. This, the offset and the number of users per page will generate our pagination.
get_results
Returns an object with the authors alone. This is similar to what get_users() returns.
The Search Form
For the search, we’re using a simple form. There’s nothing complex here.
01 | <div class="author-search"> |
02 | <h2>Search authors by name</h2> |
03 | <form method="get" id="sul-searchform" action="<?php the_permalink() ?>"> |
04 | <label for="as" class="assistive-text">Search</label> |
05 | <input type="text" class="field" name="as" id="s" placeholder="Search Authors" /> |
06 | <input type="submit" class="submit" name="submit" id="searchsubmit" value="Search Authors" /> |
10 | <h2 >Search Results for: <em><?php echo $search; ?></em></h2> |
11 | <a href="<?php the_permalink(); ?>">Back To Author Listing</a> |
14 | </div><!-- .author-search --> |
User Data and Listing the Authors
Looping through our results is fairly simple. However, getting
information about users is a bit confusing in WordPress. You see, there
are a lot of ways to get user data. We could get it directly from the
returned query; we could use general functions such as
get_userdata,
get_user_meta,
the_author_meta and
get_the_author_meta; or we could even use dedicated functions such as
the_author_link and
the_author_posts.
We’ll just use
get_userdata plus two other functions:
get_author_posts_url and
get_avatar.
01 | <?php if (!empty($authors)) { ?> |
02 | <ul class="author-list"> |
05 | foreach($authors as $author){ |
06 | $author_info = get_userdata($author->ID); |
09 | <?php echo get_avatar( $author->ID, 90 ); ?> |
10 | <h2><a href="<?php echo get_author_posts_url($author->ID); ?>"><?php echo $author_info->display_name; ?></a> - <?php echo count_user_posts( $author->ID ); ?> posts</h2> |
11 | <p><?php echo $author_info->description; ?></p> |
12 | <?php $latest_post = new WP_Query( "author=$author->ID&post_count=1" ); |
13 | if (!empty($latest_post->post)){ ?> |
14 | <p><strong>Latest Article:</strong> |
15 | <a href="<?php echo get_permalink($latest_post->post->ID) ?>"> |
16 | <?php echo get_the_title($latest_post->post->ID) ;?> |
19 | <p><a href="<?php echo get_author_posts_url($author->ID); ?> ">Read <?php echo $author_info->display_name; ?> posts</a></p> |
24 | </ul> <!-- .author-list --> |
26 | <h2>No authors found</h2> |
Pagination
We need pagination because each listing will generate two extra
queries. So, if we were listing 100 people, we would end up with 200
extra queries per page. That’s a bit much, so pagination is really
needed. Otherwise, for websites with many authors, the load could get so
heavy that it brings down the website.
01 | <nav id="nav-single" style="clear:both; float:none; margin-top:20px;"> |
02 | <h3 class="assistive-text">Post navigation</h3> |
03 | <?php if ($page != 1) { ?> |
04 | <span class="nav-previous"><a rel="prev" href="<?php the_permalink() ?>page/<?php echo $page - 1; ?>/"><span class="meta-nav">←</span> Previous</a></span> |
07 | <?php if ($page < $total_pages ) { ?> |
08 | <span class="nav-next"><a rel="next" href="<?php the_permalink() ?>page/<?php echo $page + 1; ?>/">Next <span class="meta-nav">→</span></a></span> |
Final Thoughts
We’ve discussed the code for an authors listing, but it has so many more uses:
- List your company’s employees;
- Showcase users who have won a competition (by listing users with the role of “winners”);
- Present your company’s departments, each with its respective team (based on user roles).
If you allow users to register on your website, you could use more or
less the same code to generate any listing of users based on your
needs. If you require users to log in in order to comment (an effective
way to stop automated spam), then listing users and their number of
comments could increase engagement.
Have you used something similar for a project? If so, let us know in the comments!