This entry is part 4 of 5 in the Working with Widgets Series
- How to Create Advanced WordPress Widgets – @wproots
- Simple WordPress Widget Template
- Simple Recent Posts Widget
- List Categories Widget Plugin and Tutorial
- Adding the Farbtastic Color Picker to your WordPress Widgets
In this tutorial I’m going to walk you through how to create a simple widget to list categories, and custom taxonomies, in your sidebar. The final result will be a complete plugin that you can drop into your wp-plugins folder and activate like any other plugin. The code for this widget will be based entirely upon the Basic Widget Template I gave you in part 1 of this series.
1 – Define Our Plugin Header
Just like any other plugin, we first need to enter all of information into the top of our main plugin file, list-categories-widget.php, so that WordPress recognizes it as a plugin.
1 2 3 4 5 6 7 8 | /*
Plugin Name: List Categories Widget
Plugin URI: https://pippinsplugins.com/list-categories-widget-plugin-and-tutorial
Description: Provides a better category list widget, includes support for custom taxonomies
Version: 1.0
Author: Pippin Williamson
Author URI: http://pippinspages.com
*/ |
2 – Setup Our Widget Class
Now we are going to write out our List Categories Widget class. By doing it like this, we will be giving ourselves easier access to WordPress widget functions that allow us to save, update, and retrieve widget options.
1 2 3 4 5 6 7 8 9 | /** * List Categories Widget Class */ class list_categories_widget extends WP_Widget { // our widget code goes here } // end class list_categories_widget // this will make our widget available for use add_action('widgets_init', create_function('', 'return register_widget("list_categories_widget");')); |
Note, the rest of the code I give you will need to be placed inside of the widget class we have just created, where I have left the comment “// our widget code goes here”.
3 – The Constructor Function
We now need to enter a simple function (inside of our widget class) that builds our widget for us.
1 2 3 4 | /** constructor -- name this the same as the class above */ function list_categories_widget() { parent::WP_Widget(false, $name = 'List Categories'); } |
Notice the $name variable. This is the name of our widget that is displayed in the widget header on the Appearance > Widgets page.
4 – The Widget HTML Output
The next function we are going to write, again inside of our widget class, is the one that will actually display the HTML output of the widget on the front end of the website. This function will pull the options from the widget panel and then create the necessary output.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | /** @see WP_Widget::widget -- do not rename this */ function widget($args, $instance) { extract( $args ); $title = apply_filters('widget_title', $instance['title']); // the widget title $number = $instance['number']; // the number of categories to show $taxonomy = $instance['taxonomy']; // the taxonomy to display $args = array( 'number' => $number, 'taxonomy' => $taxonomy ); // retrieves an array of categories or taxonomy terms $cats = get_categories($args); ?> <?php echo $before_widget; ?> <?php if ( $title ) { echo $before_title . $title . $after_title; } ?> <ul> <?php foreach($cats as $cat) { ?> <li><a href="<?php echo get_term_link($cat->slug, $taxonomy); ?>" title="<?php sprintf( __( "View all posts in %s" ), $cat->name ); ?>"><?php echo $cat->name; ?></a></li> <?php } ?> </ul> <?php echo $after_widget; ?> <?php } |
At the top of this function we are using the extract() function to retrieve the widget options, as set on the widget screen. We are going to create these options in a moment, but they are what will allow us to define how many categories we want to display, and also which taxonomy we’d like to use.
get_categories() is used to pull all of the categories or taxonomy terms from the database and store them in an array.
After we have gotten all of the categories or terms, we begin outputting the actual HTML that you see on the front end. It’s pretty simple; nothing more than an unordered list of category names that are linked to their respective archives. We have also included the necessary widget variables, such as $before_widget, to ensure that our widget displays correctly across all themes.
5 – The Update Widget Options Function
This next function will be used to update our widget options when we click the “Save” button on the widgets panel. It’s pretty straight forward, it takes the old options as an array, and also the new options as an array, then returns the new one back to the database.
1 2 3 4 5 6 7 8 9 | /** @see WP_Widget::update -- do not rename this */ function update($new_instance, $old_instance) { $instance = $old_instance; $instance['title'] = strip_tags($new_instance['title']); $instance['number'] = strip_tags($new_instance['number']); $instance['taxonomy'] = $new_instance['taxonomy']; return $instance; } |
The important thing to remember here is that each of the $instance[] options needs to match up with the options we have in our previous function, and also in our next function.
6 – The Widget Options Form
This is the last function in our widget class, and it will be used to display the widget options on the back end of the site, in the widgets panel.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | /** @see WP_Widget::form -- do not rename this */ function form($instance) { $title = esc_attr($instance['title']); $number = esc_attr($instance['number']); $exclude = esc_attr($instance['exclude']); $taxonomy = esc_attr($instance['taxonomy']); ?> <p> <label for="<?php echo $this->get_field_id('title'); ?>"><?php _e('Title:'); ?></label> <input class="widefat" id="<?php echo $this->get_field_id('title'); ?>" name="<?php echo $this->get_field_name('title'); ?>" type="text" value="<?php echo $title; ?>" /> </p> <p> <label for="<?php echo $this->get_field_id('number'); ?>"><?php _e('Number of categories to display'); ?></label> <input class="widefat" id="<?php echo $this->get_field_id('number'); ?>" name="<?php echo $this->get_field_name('number'); ?>" type="text" value="<?php echo $number; ?>" /> </p> <p> <label for="<?php echo $this->get_field_id('taxonomy'); ?>"><?php _e('Choose the Taxonomy to display'); ?></label> <select name="<?php echo $this->get_field_name('taxonomy'); ?>" id="<?php echo $this->get_field_id('taxonomy'); ?>" class="widefat"/> <?php $taxonomies = get_taxonomies(array('public'=>true), 'names'); foreach ($taxonomies as $option) { echo '<option id="' . $option . '"', $taxonomy == $option ? ' selected="selected"' : '', '>', $option, '</option>'; } ?> </select> </p> <?php } |
Remember, the $instance variables defined at the top of the function need to match the option names in step 4 and step 5.
The code for each option may look a little complex, but there’s not actually anything very complicated going on, just plain HTML form code with a couple of function to inject the ID and NAME of our widget options. These tell WordPress which options to update.
That’s it, you now have everything you need for the widget. Our widget will now be able to list all categories or terms, we will be able to specify how many we want to display, and we can also define the title of the widget.
7 – The Final Result
Our final code looks like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 | <?php /* Plugin Name: List Categories Widget Plugin URI: https://pippinsplugins.com/list-categories-widget-plugin-and-tutorial Description: Provides a better category list widget, includes support for custom taxonomies Version: 1.0 Author: Pippin Williamson Author URI: http://184.173.226.218/~pippin */ /** * List Categories Widget Class */ class list_categories_widget extends WP_Widget { /** constructor -- name this the same as the class above */ function list_categories_widget() { parent::WP_Widget(false, $name = 'List Categories'); } /** @see WP_Widget::widget -- do not rename this */ function widget($args, $instance) { extract( $args ); $title = apply_filters('widget_title', $instance['title']); // the widget title $number = $instance['number']; // the number of categories to show $taxonomy = $instance['taxonomy']; // the taxonomy to display $args = array( 'number' => $number, 'taxonomy' => $taxonomy ); // retrieves an array of categories or taxonomy terms $cats = get_categories($args); ?> <?php echo $before_widget; ?> <?php if ( $title ) { echo $before_title . $title . $after_title; } ?> <ul> <?php foreach($cats as $cat) { ?> <li><a href="<?php echo get_term_link($cat->slug, $taxonomy); ?>" title="<?php sprintf( __( "View all posts in %s" ), $cat->name ); ?>"><?php echo $cat->name; ?></a></li> <?php } ?> </ul> <?php echo $after_widget; ?> <?php } /** @see WP_Widget::update -- do not rename this */ function update($new_instance, $old_instance) { $instance = $old_instance; $instance['title'] = strip_tags($new_instance['title']); $instance['number'] = strip_tags($new_instance['number']); $instance['taxonomy'] = $new_instance['taxonomy']; return $instance; } /** @see WP_Widget::form -- do not rename this */ function form($instance) { $title = esc_attr($instance['title']); $number = esc_attr($instance['number']); $exclude = esc_attr($instance['exclude']); $taxonomy = esc_attr($instance['taxonomy']); ?> <p> <label for="<?php echo $this->get_field_id('title'); ?>"><?php _e('Title:'); ?></label> <input class="widefat" id="<?php echo $this->get_field_id('title'); ?>" name="<?php echo $this->get_field_name('title'); ?>" type="text" value="<?php echo $title; ?>" /> </p> <p> <label for="<?php echo $this->get_field_id('number'); ?>"><?php _e('Number of categories to display'); ?></label> <input class="widefat" id="<?php echo $this->get_field_id('number'); ?>" name="<?php echo $this->get_field_name('number'); ?>" type="text" value="<?php echo $number; ?>" /> </p> <p> <label for="<?php echo $this->get_field_id('taxonomy'); ?>"><?php _e('Choose the Taxonomy to display'); ?></label> <select name="<?php echo $this->get_field_name('taxonomy'); ?>" id="<?php echo $this->get_field_id('taxonomy'); ?>" class="widefat"/> <?php $taxonomies = get_taxonomies(array('public'=>true), 'names'); foreach ($taxonomies as $option) { echo '<option id="' . $option . '"', $taxonomy == $option ? ' selected="selected"' : '', '>', $option, '</option>'; } ?> </select> </p> <?php } } // end class list_categories_widget add_action('widgets_init', create_function('', 'return register_widget("list_categories_widget");')); ?> |
This is the complete code that can be dropped into a php file inside of wp-plugins.
Pingback: TutsPress | 20+ Helpful Free Wordpress Plugins Powered by Pippins
Thanks for your tutorial, but how do I select a single parent category?
I’m not quite sure what you’re asking. There’s no difference between selecting a parent or child category.
Hi PinPin,
I am finding a wordpress plugin which helps me to create a category list in widget but only categories which are chosen by me show. Please introduce some wp plugins to me.
Thanks so much !
Hi Pippin,
I’m seeing a bit of an issue with this plugin. When selecting a taxonomy (other than the first one for testing purposes) in the select drop down, then clicking save, all is well. However, re-loading the widget admin page and opening up the widget again shows the select is now sitting at the first option again. Inspecting the element with Firebug shows that the ‘selected’ code is still with the correct option, but — of course — not re-selecting the desired option means that the first option is saved again.
I’ve installed a completely vanilla WP 3.4.2 to test this, installing only your plugin here. Any ideas?
Thanks very much!
C.
Hi Pippin,
I’ve tracked down the problem. In line 75 as listed above, you have a “/” just before the closing “>” of the select element which was doing weird things. I removed it it’s going great now.
Hope that helps.
C.
Great, thanks for letting me know.
Hi there, thanks for this. I have been looking for examples of plugin development that use OO principles and this is exactly the sort ofthing I was looking for. Very useful.
Hi Pippins,
Your demo is really great. I am looking for a sample widget plugin and I found yours.
I will use this as a start.
Thanks for your guide, Pippins!
Everything is just fine , thank you. I have a request: How can we show the amount of text on the category. Thank you in advance for your answer . I translated using Google translate , sorry if wrong anymore 🙂
The amount of text? Do you mean the number of items in the category?
Yes, how can indicate the number of categories of content , you show examples
Hey Pippin
How would the plugin be modified to to display the contents of the posts for a selected term?
Awesome awesome awesome tutorial! Thanks for taking the time to pen this down for us! Much appreciated!
How would I go about changing/adding so that it only show the parent and its children display of the current post or category it is currently shown on?
For instance, I have 5 top categories and each have children categories. If I click on one of the parents, I want it show this parent as well as the children of this parent. If I’m in a post tagged with one of the children, I need to see the parent and children, not any other categories, not any grandchildren either.
Any help would be super appreciated!
There is a “child_of” parameter that you can pass to the function. You will need to first get the category ID of the current post and then pass that to the function.
Thanks for your code.
It looks like the download button for this is broken.
May be just use modern ready plugins, like
https://wordpress.org/plugins/iks-menu/
or
https://ru.wordpress.org/plugins/nextend-accordion-menu/
?
PLease, how i adjust it to select all created categories in my wordpress database