{"id":141266,"date":"2015-05-24T08:00:49","date_gmt":"2015-05-24T12:00:49","guid":{"rendered":"http:\/\/premium.wpmudev.org\/blog\/?p=141266"},"modified":"2015-05-23T18:33:59","modified_gmt":"2015-05-23T22:33:59","slug":"author-list-widget","status":"publish","type":"post","link":"https:\/\/wpmudev.com\/blog\/author-list-widget\/","title":{"rendered":"How to Create a Custom Author List Widget in WordPress"},"content":{"rendered":"<p>For many websites good authors are <em>the<\/em> most important asset they have. Showcasing them properly can be an important concern and WordPress doesn&#8217;t really have anything powerful out-of-the-box. Most of the widgets in the WordPress Plugin Directory\u00a0are a little basic so I thought it would be a good idea to create something really powerful myself.<\/p>\n<p>In this Weekend WordPress Project\u00a0I&#8217;ll show you how you can create your own\u00a0\u2013 simpler \u2013\u00a0widget, and then I&#8217;ll show you the actual plugin I adopted in the directory\u00a0and how I\u00a0added versatile features to make it as flexible as possible for others.<\/p>\n<p>Let&#8217;s get started.<\/p>\n<h2>Creating Our Own Widget<\/h2>\n<p>Let&#8217;s start by doing things on our own. This requires <a href=\"https:\/\/wpmudev.com\/blog\/wordpress-plugin-development-guide\/\" target=\"_blank\">creating a plugin<\/a> and \u2013 within it \u2013\u00a0<a href=\"https:\/\/wpmudev.com\/blog\/how-to-build-wordpress-widgets-like-a-pro\/\" target=\"_blank\">creating a widget<\/a>. Here&#8217;s the nutshell version of the two linked articles:<\/p>\n<ol>\n<li>Create a folder in your <code>wp-content\/plugins<\/code> folder &#8211; name it <code>my-author-list<\/code><\/li>\n<li>Within this folder create a file named <code>my-author-list.php<\/code>, this will be your main plugin file<\/li>\n<li>Paste the following code within it (feel free to replace the author info in there)<\/li>\n<\/ol>\n<div class=\"gist\" data-gist=\"b8cc9371321b2fc74e60554c4968c9dd\" data-gist-file=\"plugin.php\"><a class=\"loading\" href=\"https:\/\/gist.github.com\/b8cc9371321b2fc74e60554c4968c9dd.js?file=plugin.php\">Loading gist b8cc9371321b2fc74e60554c4968c9dd<\/a><div class=\"gist-consent-notice\" style=\"display:none\"><p>Please <a href=\"javascript:Cookiebot.renew()\">update your cookie preferences<\/a> to enable preference cookies to view this gist.<\/p><\/div><\/div>\n<p>At this stage, you have made a fully functional plugin, although it doesn&#8217;t do anything yet apart from show up in the backend. Go ahead and activate it now.<\/p>\n<p>Next, let&#8217;s paste the skeleton code we&#8217;ll need to make a widget. Add the following to the file:<\/p>\n<div class=\"gist\" data-gist=\"250ce27c2fb54ce539c00927c6e0468b\" data-gist-file=\"widget-skeleton.php\"><a class=\"loading\" href=\"https:\/\/gist.github.com\/250ce27c2fb54ce539c00927c6e0468b.js?file=widget-skeleton.php\">Loading gist 250ce27c2fb54ce539c00927c6e0468b<\/a><div class=\"gist-consent-notice\" style=\"display:none\"><p>Please <a href=\"javascript:Cookiebot.renew()\">update your cookie preferences<\/a> to enable preference cookies to view this gist.<\/p><\/div><\/div>\n<p>To create a widget you need to extend the <code>WP_Widget<\/code> with your own sub-class. Within this sub-class you need to define a few functions, which govern how the widgets work. Don&#8217;t worry if you don&#8217;t know what classes are, the syntax is pretty simple.<\/p>\n<p>All you need to know is what those four functions in there do and you can code within them throughout this exercise. The <code>__construct()<\/code> function basically adds our widget to WordPress. It contains the name, description and a few other details of the widget.<\/p>\n<p>The <code>form()<\/code> function governs the backend form, which shows up when you add the widget to a widget area. This is where you can create inputs for additional options, like how many authors to show, the widget title, and so on.<\/p>\n<p>The <code>widget()<\/code> function takes care of the front-end display. Any code in there will be shown where the widget is supposed to be on our page.<\/p>\n<p>The <code>update()<\/code> function will not necessarily be needed, in fact, in this example we can discard it. This function can process data that is submitted when the widget is saved in the backend. This is great for retrieving API data based on the user input or perhaps transforming the input itself. I&#8217;ll discard this for now since we don&#8217;t need it.<\/p>\n<h3>Adding Widget Options<\/h3>\n<p>Let&#8217;s stick to the basics for now. A simple widget title, author count, order by and order direction field should do. I like to take the following steps for each.<\/p>\n<ol>\n<li>Determine the current value for each field<\/li>\n<li>Determine the possible values for dropdowns, radio or checkboxes<\/li>\n<li>Output the field<\/li>\n<\/ol>\n<p>Here&#8217;s the code I would use for the three fields we discussed:<\/p>\n<div class=\"gist\" data-gist=\"42df9f34d246ae9504625fe7f68a282a\" data-gist-file=\"form.php\"><a class=\"loading\" href=\"https:\/\/gist.github.com\/42df9f34d246ae9504625fe7f68a282a.js?file=form.php\">Loading gist 42df9f34d246ae9504625fe7f68a282a<\/a><div class=\"gist-consent-notice\" style=\"display:none\"><p>Please <a href=\"javascript:Cookiebot.renew()\">update your cookie preferences<\/a> to enable preference cookies to view this gist.<\/p><\/div><\/div>\n<p>The <code>$instance<\/code> variable holds the current value of the fields, ie: the values the user has saved. In the first block I check those values. If they are empty I set a default for each field. Next up are field options.<\/p>\n<p>For each field where I have a pre-set number of options I create an array for them. This may seem a little redundant for the order field but it makes the field output code more modular and it is also easier to handle the currently selected value.<\/p>\n<p>Next up are the fields. They are perfectly normal HTML fields, the only two things you need to remember are to use the <code>$this-&gt;get_field_name()<\/code> and <code>$this-&gt;get_field_id()<\/code> methods. These are needed for WordPress to be able to save our data to the correct widget. Other than that, all the code is simple HTML and PHP loops.<\/p>\n<p>At this stage you should be able to drag the widget into any widget area and save its data.<\/p>\n<h3>Displaying Our Widget<\/h3>\n<p>When displaying a widget you should always be mindful of its surroundings. When a widget are is defined using the <a href=\"https:\/\/codex.wordpress.org\/Function_Reference\/register_sidebar\" target=\"_blank\"><code>reregister_sidebar()<\/code><\/a> function a number of parameters can be defined such as <code>before_title<\/code> and <code>before_widgets<\/code>. These are passed as the first parameter for our <code>widget()<\/code> function, the second parameter holds the widget&#8217;s instance variables, the saved data for the widget.<\/p>\n<p>This is why almost all widget display functions should use the following skeleton code:<\/p>\n<div class=\"gist\" data-gist=\"2433331b8818803c042b96cac46784ba\" data-gist-file=\"display-skeleton.php\"><a class=\"loading\" href=\"https:\/\/gist.github.com\/2433331b8818803c042b96cac46784ba.js?file=display-skeleton.php\">Loading gist 2433331b8818803c042b96cac46784ba<\/a><div class=\"gist-consent-notice\" style=\"display:none\"><p>Please <a href=\"javascript:Cookiebot.renew()\">update your cookie preferences<\/a> to enable preference cookies to view this gist.<\/p><\/div><\/div>\n<p>This code will display any code that is supposed to precede and succeed the widget as well as any code that should be added before the title, the title itself and any code after the title.<\/p>\n<h3>Getting Authors<\/h3>\n<p>We&#8217;ll be using the <a href=\"https:\/\/codex.wordpress.org\/Function_Reference\/get_users\" target=\"_blank\"><code>get_users()<\/code><\/a> function to retrieve our authors, all we need to do is pass our parameters to it. Here&#8217;s the code, which should be pasted inside the widget display skeleton where it says &#8220;\/\/ Main Widget Code Here&#8221;:<\/p>\n<div class=\"gist\" data-gist=\"0c7db01d8ecf2137362a9e95d686897f\" data-gist-file=\"get_users.php\"><a class=\"loading\" href=\"https:\/\/gist.github.com\/0c7db01d8ecf2137362a9e95d686897f.js?file=get_users.php\">Loading gist 0c7db01d8ecf2137362a9e95d686897f<\/a><div class=\"gist-consent-notice\" style=\"display:none\"><p>Please <a href=\"javascript:Cookiebot.renew()\">update your cookie preferences<\/a> to enable preference cookies to view this gist.<\/p><\/div><\/div>\n<p>The <code>$users<\/code> variable should contain an array of user objects. We now need to cycle through them using a simple loop and display any information we want. Here&#8217;s an example which shows the avatar and the user&#8217;s name, each linking to the user&#8217;s url. Paste the code right below the call to the <code>get_users<\/code> function.<\/p>\n<div class=\"gist\" data-gist=\"18020957353f7efa0428ccd0dcd1b068\" data-gist-file=\"user_loop.php\"><a class=\"loading\" href=\"https:\/\/gist.github.com\/18020957353f7efa0428ccd0dcd1b068.js?file=user_loop.php\">Loading gist 18020957353f7efa0428ccd0dcd1b068<\/a><div class=\"gist-consent-notice\" style=\"display:none\"><p>Please <a href=\"javascript:Cookiebot.renew()\">update your cookie preferences<\/a> to enable preference cookies to view this gist.<\/p><\/div><\/div>\n<p>Now you should see a list of users, which you can control using the settings defined in the widget. It won&#8217;t look super awesome, but we can fix that by adding some styling.<\/p>\n<h3>Adding Some Style<\/h3>\n<p>To add styles the WordPress way we need to enqueue a stylesheet. The best way to do accomplish this is in two steps.<\/p>\n<ol>\n<li>First we register it with WordPress, then, within the <code>widget()<\/code> function we enqueue it. This ensures that WordPress is aware of the existence of our stylesheet but only actually adds it to the page when it is needed.<\/li>\n<\/ol>\n<p>To register the stylesheet add the following within the <code>__construct()<\/code> method of our class:<\/p>\n<div class=\"gist\" data-gist=\"895dc034e4da43bf4dc81242ed55f9c4\" data-gist-file=\"enqueue_action.php\"><a class=\"loading\" href=\"https:\/\/gist.github.com\/895dc034e4da43bf4dc81242ed55f9c4.js?file=enqueue_action.php\">Loading gist 895dc034e4da43bf4dc81242ed55f9c4<\/a><div class=\"gist-consent-notice\" style=\"display:none\"><p>Please <a href=\"javascript:Cookiebot.renew()\">update your cookie preferences<\/a> to enable preference cookies to view this gist.<\/p><\/div><\/div>\n<ol>\n<li>Then, create a <code>widget_styles()<\/code> function within the class. Don&#8217;t worry about the name being generic, that&#8217;s why it is great to work inside the class, your function names won&#8217;t clash with anyone else&#8217;s.<\/li>\n<\/ol>\n<div class=\"gist\" data-gist=\"89b221e4b2b26762ca43fdc980fadc24\" data-gist-file=\"register-style.php\"><a class=\"loading\" href=\"https:\/\/gist.github.com\/89b221e4b2b26762ca43fdc980fadc24.js?file=register-style.php\">Loading gist 89b221e4b2b26762ca43fdc980fadc24<\/a><div class=\"gist-consent-notice\" style=\"display:none\"><p>Please <a href=\"javascript:Cookiebot.renew()\">update your cookie preferences<\/a> to enable preference cookies to view this gist.<\/p><\/div><\/div>\n<p>Finally, at the top of the <code>widget()<\/code> function add the following to make sure the stylesheet is added whenever the widget is displayed:<\/p>\n<div class=\"gist\" data-gist=\"21c9f57b8ca893e7c37a1ced71b11497\" data-gist-file=\"enqueue-style.php\"><a class=\"loading\" href=\"https:\/\/gist.github.com\/21c9f57b8ca893e7c37a1ced71b11497.js?file=enqueue-style.php\">Loading gist 21c9f57b8ca893e7c37a1ced71b11497<\/a><div class=\"gist-consent-notice\" style=\"display:none\"><p>Please <a href=\"javascript:Cookiebot.renew()\">update your cookie preferences<\/a> to enable preference cookies to view this gist.<\/p><\/div><\/div>\n<p>Add any style you like within the stylesheet, it will be applied to your widget. It may be a good idea to wrap your widget in a specific class so you can target it effectively and many <code>before_widget<\/code> code sections will also include your widget&#8217;s class.<\/p>\n<h2>Using The Top Authors Plugin<\/h2>\n<div  class=\"wpdui-pic-regular  \">\n<figure class=\"wp-caption aligncenter\" data-caption=\"true\"><img loading=\"lazy\" decoding=\"async\" class=\"attachment-735x735\" src=\"https:\/\/wpmudev.com\/blog\/wp-content\/uploads\/2015\/05\/top-authors-settings.jpg\" alt=\"The Top Authors widget settings.\" width=\"490\" height=\"735\" \/><figcaption class=\"wp-caption-text\">The Top Authors widget settings.<\/figcaption><\/figure>\n<\/div>\n<p>I&#8217;m working on a large website rebuild at the moment and one of our key decisions was to either use existing plugins for everything we need, or to code our own general-use plugins if needed. We created a couple of plugins due to this policy.<\/p>\n<p>We broke our policy and used\u00a0<a href=\"https:\/\/wordpress.org\/plugins\/top-authors\/\" target=\"_blank\">Top Authors<\/a>\u00a0for two reasons:\u00a0It already existed and its developer <a href=\"https:\/\/twitter.com\/sebvandijk\" target=\"_blank\">Seb Van Dijk<\/a>\u00a0generously donated the plugin to us, which we&#8217;ve adopted and taken over. We recoded it a bit, added some new features and released the update to the\u00a0WordPress Plugin Directory.<\/p>\n<div  class=\"wpdui-pic-right  \">\n\n\n\n<figure class=\"wp-caption alignright\" data-caption=\"true\"><img loading=\"lazy\" decoding=\"async\" class=\"attachment-490x490\" src=\"https:\/\/wpmudev.com\/blog\/wp-content\/uploads\/2015\/05\/top-authors.jpg\" alt=\"This is what the Top Authors widget looks like on the front-end.\" width=\"490\" height=\"183\" \/><figcaption class=\"wp-caption-text\">This is what the Top Authors widget looks like on the front-end.<\/figcaption><\/figure>\n\n<p>Top Authors went beyond the simple uncustomizable text or text\/Gravatar list. It allowed us to add our own custom template to be used in the widget front-end. We kept this great feature, adding some defaults in the process, and\u00a0extended\u00a0it with a number of hooks.<\/p>\n\n\n\n\n<\/div>\n<p>The widget options give you the option to include\/exclude roles, choose which post types to take into consideration and select a display from a preset list, or create your own. We&#8217;ve also added an additional ID you can pass to each widget which allows you to use the <code>ta\/post_query<\/code> hook to modify the authors you want to display for each widget.<\/p>\n<h3>Extending Top Authors<\/h3>\n<p>Top Authors already gives you control over the display but you can do a lot more with the hooks, especially the one I mentioned earlier, &#8211; <code>ta\/post_query<\/code>. This hook allows you to modify the query that looks up the posts based on which the authors are listed.<\/p>\n<p>Let&#8217;s back up a bit and figure out how top authors works. Instead of retrieving users directly, we first retrieve posts, and then look at the authors for those posts. The reasoning behind this is that it allows for a much more flexible listing of authors because it allows for the list to be narrowed down based on any criteria.<\/p>\n<p>For example, say you want to list your top authors, but only for posts published on weekends that are assigned the featured category. You could restrict the Top Authors widget like this:<\/p>\n<div class=\"gist\" data-gist=\"1de4c4f5151104e03aaf5e8ad09f9d7b\" data-gist-file=\"restrict-widget.php\"><a class=\"loading\" href=\"https:\/\/gist.github.com\/1de4c4f5151104e03aaf5e8ad09f9d7b.js?file=restrict-widget.php\">Loading gist 1de4c4f5151104e03aaf5e8ad09f9d7b<\/a><div class=\"gist-consent-notice\" style=\"display:none\"><p>Please <a href=\"javascript:Cookiebot.renew()\">update your cookie preferences<\/a> to enable preference cookies to view this gist.<\/p><\/div><\/div>\n<p>You can use any parameters that <a href=\"https:\/\/codex.wordpress.org\/Class_Reference\/WP_Query\" target=\"_blank\">WP_Query<\/a> usually takes since they are passed directly to it. Since the second parameter of the function (the <code>$instance<\/code> variable) contains the widget&#8217;s details you can even narrow the use of this function down to a specific single widget using the widget&#8217;s id.<\/p>\n<h2>Conclusion<\/h2>\n<p>While there are a bunch of simple <a href=\"https:\/\/wordpress.org\/plugins\/search\/author+widget\/\" target=\"_blank\">author widgets<\/a> around, I didn&#8217;t really find any of them to be flexible enough for my own needs. If you need a simple list, a lot of them will do. But if you need something more customizable I think Top Authors is a great choice, or just go full coder and do it yourself!<\/p>\n<p><strong>If you have any questions or tips for listing authors let us know in the comments below.<\/strong><\/p>\n","protected":false},"excerpt":{"rendered":"<p>For many websites, good authors are their most important asset. Unfortunately, WordPress doesn&#8217;t offer an elegant solution for displaying author profiles out-of-the-box. Most of the widgets in the WordPress Plugin Directory are fairly basic, so in this Weekend WordPress Project we show you how to create your own widget.<\/p>\n","protected":false},"author":344049,"featured_media":137545,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"blog_reading_time":"","wds_primary_category":0,"wds_primary_tutorials_categories":0,"footnotes":""},"categories":[263],"tags":[9798],"tutorials_categories":[],"class_list":["post-141266","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-tutorials","tag-weekend-wordpress-projects"],"_links":{"self":[{"href":"https:\/\/wpmudev.com\/blog\/wp-json\/wp\/v2\/posts\/141266","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wpmudev.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/wpmudev.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/wpmudev.com\/blog\/wp-json\/wp\/v2\/users\/344049"}],"replies":[{"embeddable":true,"href":"https:\/\/wpmudev.com\/blog\/wp-json\/wp\/v2\/comments?post=141266"}],"version-history":[{"count":16,"href":"https:\/\/wpmudev.com\/blog\/wp-json\/wp\/v2\/posts\/141266\/revisions"}],"predecessor-version":[{"id":222807,"href":"https:\/\/wpmudev.com\/blog\/wp-json\/wp\/v2\/posts\/141266\/revisions\/222807"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/wpmudev.com\/blog\/wp-json\/wp\/v2\/media\/137545"}],"wp:attachment":[{"href":"https:\/\/wpmudev.com\/blog\/wp-json\/wp\/v2\/media?parent=141266"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wpmudev.com\/blog\/wp-json\/wp\/v2\/categories?post=141266"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wpmudev.com\/blog\/wp-json\/wp\/v2\/tags?post=141266"},{"taxonomy":"tutorials_categories","embeddable":true,"href":"https:\/\/wpmudev.com\/blog\/wp-json\/wp\/v2\/tutorials_categories?post=141266"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}