{"id":132869,"date":"2014-11-03T08:00:00","date_gmt":"2014-11-03T13:00:00","guid":{"rendered":"http:\/\/premium.wpmudev.org\/blog\/?p=132869"},"modified":"2014-11-03T08:13:30","modified_gmt":"2014-11-03T13:13:30","slug":"adding-custom-widgets-to-the-wordpress-admin-dashboard","status":"publish","type":"post","link":"https:\/\/wpmudev.com\/blog\/adding-custom-widgets-to-the-wordpress-admin-dashboard\/","title":{"rendered":"Adding Custom Widgets to the WordPress Admin Dashboard"},"content":{"rendered":"<p>Have you ever wished that your WordPress dashboard was a more useful place?<\/p>\n<p>Sure, there are plugins that add modules there but there are countless metrics and shortcuts you may want to add yourself. In this post I&#8217;ll show you how you can add your own &#8211; completely customized &#8211; dashboard widgets easily.<\/p>\n<figure id=\"attachment_133286\" class=\"wp-caption aligncenter\" data-caption=\"true\"><a rel=\"lightbox[132869]\" class=\"blog-thumbnail\" href=\"https:\/\/wpmudev.com\/blog\/wp-content\/uploads\/2014\/10\/dashboard.jpg\" target=\"_blank\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-133286\" src=\"https:\/\/wpmudev.com\/blog\/wp-content\/uploads\/2014\/10\/dashboard.jpg\" alt=\"WordPress Dashboard\" width=\"700\" height=\"192\" \/><\/a><figcaption class=\"wp-caption-text\">Create your own dashboard widget.<\/figcaption><\/figure>\n<h2>A Basic Dashboard Widget<\/h2>\n<p>The anatomy of a dashboard widget is extremely simple. First you need to use the <code>wp_add_dashboard_widget()<\/code> function to register it with WordPress. Then you create a function which handles the content display. Here&#8217;s the template code you can use to create one quickly.<\/p>\n<div class=\"gist\" data-gist=\"6de7a302cf7a894e75d0c618d9754e1e\" data-gist-file=\"skeleton.php\"><a class=\"loading\" href=\"https:\/\/gist.github.com\/6de7a302cf7a894e75d0c618d9754e1e.js?file=skeleton.php\">Loading gist 6de7a302cf7a894e75d0c618d9754e1e<\/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>Before I break that down, don&#8217;t forget that this should be placed in a plugin. If you want to test this real quick you can also get away with adding it to your theme&#8217;s <code>functions.php<\/code> file.<\/p>\n<p>The first step is to hook a function into <code>wp_dashboard_setup<\/code>. The contents of this function is a simple call to <code>wp_add_dashboard_widget()<\/code> with three parameters:<\/p>\n<ul>\n<li>Widget slug<\/li>\n<li>Widget title<\/li>\n<li>Display function<\/li>\n<\/ul>\n<p>The second step is creating the display function <code>my_dashboard_widget_display()<\/code> and filling it with content.<\/p>\n<h2>Forcing Widgets to the Top<\/h2>\n<p>In some situations, you may want to show important information or functionality at the top of your dashboard. WordPress doesn&#8217;t have a great API for handling this, but with some fiddling around you can get it done. We&#8217;ll need to add some extra code into our registration function, here&#8217;s the full code for an example widget.<\/p>\n<div class=\"gist\" data-gist=\"7a4c867a7b70b9526ae96359c98d26aa\" data-gist-file=\"example.php\"><a class=\"loading\" href=\"https:\/\/gist.github.com\/7a4c867a7b70b9526ae96359c98d26aa.js?file=example.php\">Loading gist 7a4c867a7b70b9526ae96359c98d26aa<\/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>Seven additional lines for a simple rearranging is a bit much but since no other method is available, this will have to do. The first step is to globalize the <code>$wp_meta_boxes<\/code> variable which contains information about all registered widgets. To make things easier on the eyes I&#8217;ve separated out the widgets which are displayed on the dashboard into the <code>$dashboard<\/code> variable.<\/p>\n<p>The next step is to grab our registered widget from the array of widgets. This is stored in the <code>$my_widget<\/code> variable because we need to unset it in the next line and then re-add it.<\/p>\n<p>The next step is to merge the contents of <code>$my_widget<\/code> and <code>$dashboard<\/code>. The <code>array_merge()<\/code> function appends the second array to the first so our widget will now be the first one in the new <code>$sorted_dashboard<\/code> array. The last step is to replace the original dashboard array with our new sorted one.<\/p>\n<h2>Adding Functionality<\/h2>\n<p>The main way you can enhance dashboard widgets is by creating some nice styles or applying some Javascript functionality. Let&#8217;s create a widget that shows the number of comments our website has received each week for the past five weeks. This will be a simplified example, a proof of concept if you will.<\/p>\n<figure id=\"attachment_132879\" class=\"wp-caption aligncenter\" data-caption=\"true\"><a rel=\"lightbox[132869]\" class=\"blog-thumbnail\" href=\"https:\/\/wpmudev.com\/blog\/wp-content\/uploads\/2014\/10\/Comment-Trends.png\" target=\"_blank\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-132879\" src=\"https:\/\/wpmudev.com\/blog\/wp-content\/uploads\/2014\/10\/Comment-Trends.png\" alt=\"The end result of our efforts\" width=\"554\" height=\"267\" \/><\/a><figcaption class=\"wp-caption-text\">The end result of our efforts<\/figcaption><\/figure>\n<h3>HTML Structure<\/h3>\n<p>We&#8217;ll be building the example above with CSS only, no Javascript required. To get it done we will use the following HTML structure:<\/p>\n<div class=\"gist\" data-gist=\"95b835afb98b623a023bd778ada24067\" data-gist-file=\"html.html\"><a class=\"loading\" href=\"https:\/\/gist.github.com\/95b835afb98b623a023bd778ada24067.js?file=html.html\">Loading gist 95b835afb98b623a023bd778ada24067<\/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>It will be styled using a CSS file and also some inline CSS which will take care of the heights and widths for us.<\/p>\n<h3>Styling the Bars<\/h3>\n<p>The height of the whole container (<code>.comment-stat-bars<\/code>) is a fixed 120px high. The bars themselves are actually also 120px hight. The seemingly different heights are achieved by adding a top border height. This ensures that the bars start from the bottom and by setting the <code>overflow:hidden<\/code> on the container we can hide the unwanted bits.<\/p>\n<p>The stylesheet is added in the usual fashion, by enqueueing it:<\/p>\n<div class=\"gist\" data-gist=\"e18ee46ac24636cb40447ef22e1ff272\" data-gist-file=\"enqueue.php\"><a class=\"loading\" href=\"https:\/\/gist.github.com\/e18ee46ac24636cb40447ef22e1ff272.js?file=enqueue.php\">Loading gist e18ee46ac24636cb40447ef22e1ff272<\/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>Note that we check the value of the <code>$hook<\/code> variable to make sure the style is only used on the dashboard page, there really is no need for it anywhere else. If you&#8217;re adding the code to your theme&#8217;s functions file you&#8217;ll want to use <code>get_template_directory_uri()<\/code> instead of <code>plugins_uri()<\/code>.<\/p>\n<p>The content of the stylesheet itself is the following, the remaining few styles will be added inline.<\/p>\n<div class=\"gist\" data-gist=\"9a1fca4369b69da58cd25cfd7cd41d59\" data-gist-file=\"style.css\"><a class=\"loading\" href=\"https:\/\/gist.github.com\/9a1fca4369b69da58cd25cfd7cd41d59.js?file=style.css\">Loading gist 9a1fca4369b69da58cd25cfd7cd41d59<\/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<h3>Calculating Heights<\/h3>\n<p>Instead of grabbing comment counts, let&#8217;s work with an array of numbers similar to what we will end up with in the end:<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\n$comment_counts = array( 20, 29, 40, 33, 17 );\r\n<\/pre>\n<p>This array represents the comments we received each week for the past 5 weeks. So based on this, how do we figure out the bar dimensions. Let&#8217;s start with width since it&#8217;s easier.<\/p>\n<p>In the stylesheet we&#8217;ve added a 1% margin to each side of the bars. This means that for each bar we have, we have 2% less space available to divide between the bars. So if we use 100% as the total width we can figure out the percentage width of one bar like this:<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\n\/\/ ( 100 \/ number of bars ) - 2\r\n$data_points = count( $comment_counts );\r\n$bar_width = 100 \/ $data_points - 2\r\n<\/pre>\n<p>On to the height! The bar with the highest value will always be set to fill out the whole height of the container. In our example, the third bar (with the value of 40) is the largest so it will be the maximum height of 120px. Whenever a bar is smaller we add a top margin to it.<\/p>\n<p>Exactly how much top margin is added depends on ratio between the size of a bar and the largest bar in the set. In our example the first bar is exactly half the size of the third bar. Therefore we would need to add a 60px top margin, exactly half of the maximum 120px. Here&#8217;s how this looks in code:<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\n$highest_value = max( $comment_counts );\r\nforeach( $comment_counts as $count ) :\r\n\t$count_percentage = $count\/$highest_value;\r\n\t$bar_height = $total_height * $count_percentage;\r\n\t$border_width = $total_height - $bar_height;\r\n}\r\n<\/pre>\n<h3>Displaying A Static Graph<\/h3>\n<p>If we put everything we&#8217;ve done together we&#8217;ll end up with a nice little bar chart, although the numbers are hard coded in. Let&#8217;s take a look!<\/p>\n<div class=\"gist\" data-gist=\"b9ab3a82e64a5ac4e4f40c489491be7e\" data-gist-file=\"graph.php\"><a class=\"loading\" href=\"https:\/\/gist.github.com\/b9ab3a82e64a5ac4e4f40c489491be7e.js?file=graph.php\">Loading gist b9ab3a82e64a5ac4e4f40c489491be7e<\/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<h3>Pulling Comment Counts<\/h3>\n<p>The last step is grabbing the comment counts dynamically. Unfortunately, WordPress does not have a function for this so we&#8217;ll need to write our own little query. The version below is quick and dirty but will work. Simply replace the array with the following:<\/p>\n<div class=\"gist\" data-gist=\"18b469efacd0a8461c54d1919abb708e\" data-gist-file=\"commentcount.php\"><a class=\"loading\" href=\"https:\/\/gist.github.com\/18b469efacd0a8461c54d1919abb708e.js?file=commentcount.php\">Loading gist 18b469efacd0a8461c54d1919abb708e<\/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>All that is going on is we&#8217;re pulling the number of comments from the database 5 times. In each iteration of the loop we&#8217;re going back one week. In the first iteration we&#8217;re pulling comments between now and 7 days ago. In the second iteration we&#8217;re pilling comments between 7 and 14 days ago, and so on.<\/p>\n<p>In a real world scenario, this would be done with a single query, the array would be compiled based on that.<\/p>\n<h2>Conclusion<\/h2>\n<p>In conclusion, dashboard widgets offer us a great way to communicate things to ourselves and our website&#8217;s staff. Aside from static content we can spice things up with CSS and add great functionality using Javascript.<\/p>\n<p>In addition to pulling data from WordPress we can look to third party API&#8217;s for data as well. You can grab customized stats from providers like Mailchimp, Google Analytics, Twitter, and so on.<\/p>\n<p><strong>Let us know in the comments if you&#8217;ve built any great dashboard widgets or if you have any ideas for some useful ones!<\/strong><\/p>\n<p><em>Image credit: Nissan Note 2014 image by <a href=\"https:\/\/flic.kr\/p\/nryZRy\" target=\"_blank\">K\u0101rlis Dambr\u0101ns<\/a><\/em><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Have you ever wished that your WordPress dashboard was a more useful place? Sure, there are plugins that add modules there but there are countless metrics and shortcuts you may want to add yourself. In this post I&#8217;ll show you how you can add your own &#8211; completely customized &#8211; dashboard widgets easily. A Basic [&hellip;]<\/p>\n","protected":false},"author":344049,"featured_media":206648,"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":[52],"tutorials_categories":[],"class_list":["post-132869","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-tutorials","tag-widgets"],"_links":{"self":[{"href":"https:\/\/wpmudev.com\/blog\/wp-json\/wp\/v2\/posts\/132869","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=132869"}],"version-history":[{"count":1,"href":"https:\/\/wpmudev.com\/blog\/wp-json\/wp\/v2\/posts\/132869\/revisions"}],"predecessor-version":[{"id":195102,"href":"https:\/\/wpmudev.com\/blog\/wp-json\/wp\/v2\/posts\/132869\/revisions\/195102"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/wpmudev.com\/blog\/wp-json\/wp\/v2\/media\/206648"}],"wp:attachment":[{"href":"https:\/\/wpmudev.com\/blog\/wp-json\/wp\/v2\/media?parent=132869"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wpmudev.com\/blog\/wp-json\/wp\/v2\/categories?post=132869"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wpmudev.com\/blog\/wp-json\/wp\/v2\/tags?post=132869"},{"taxonomy":"tutorials_categories","embeddable":true,"href":"https:\/\/wpmudev.com\/blog\/wp-json\/wp\/v2\/tutorials_categories?post=132869"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}