We all love a celebration, and now that Easter is over, we look forward to the next occasion. How far away is the next occasion you like to celebrate? Whatever it might be, let's build a widget plugin to add a countdown timer to our sidebar showing how long we have left to wait.
1. Getting a Head Start
There are a number of things we need to do every time we're developing a WordPress plugin, and even more specifically, a widget. Thanks to one of our authors here at Wptuts+, Tom McFarlin, we can get underway quickly by using the WordPress Widget Boilerplate.
To use the WordPress Widget Boilerplate, download it, unzip it, and move the directory widget-boilerplate into your /wp-content/plugins/ directory. Then rename it wptuts-countdowner.
Inside that directory you'll find the main PHP file, plugin.php, which we'll also rename to wptuts-countdowner.php.
Now we're ready to get into the code.
2. Re-Badging the Boilerplate
Inside the wptuts-countdowner.php file is all the heavy lifting done for us by the boilerplate. To begin with, we just need to customise it to reflect the name of our plugin. Then once we've written our own code, we can also ditch the extra bits of the boilerplate that we may not need.
The plugin header information will look like this:
<?php /* Plugin Name: TODO Plugin URI: TODO Description: TODO Version: 1.0 Author: TODO Author URI: TODO Author Email: TODO Text Domain: widget-name-locale Domain Path: /lang/ Network: false License: GPLv2 or later License URI: http://www.gnu.org/licenses/gpl-2.0.html Copyright 2012 TODO ([email protected]) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License, version 2, as published by the Free Software Foundation. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
So fix that up with the details of our plugin:
<?php /* Plugin Name: Wptuts+ Countdowner Plugin URI: TODO Description: A widget to display a countdown timer in your site's sidebar. Version: 1.0 Author: Japh Author URI: http://wp.tutsplus.com/author/Japh Text Domain: wptuts-countdowner-locale Domain Path: /lang/ Network: false License: GPLv2 or later License URI: http://www.gnu.org/licenses/gpl-2.0.html Copyright 2013 Japh This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License, version 2, as published by the Free Software Foundation. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
We'll also need to change a few references throughout the boilerplate code to change the generic references to use our plugin name. Most of the places where you'll need to do this are indicated with a 'TODO
'.
Find and replace 'widget-name
' with 'wptuts-countdowner
', and also 'Widget_name
' with 'Wptuts_Countdowner
'. Now the plugin has its own name!
Now you have a plugin you can activate in your WordPress Dashboard. Once activated, when you look under Appearance -> Widgets, you'll see the beginnings of our widget:
As you can see, it looks pretty generic at the moment. So update the following code:
// TODO: update classname and description // TODO: replace 'wptuts-countdowner-locale' to be named more plugin specific. Other instances exist throughout the code, too. parent::__construct( 'wptuts-countdowner-id', __( 'Widget Name', 'wptuts-countdowner-locale' ), array( 'classname' => 'wptuts-countdowner-class', 'description' => __( 'Short description of the widget goes here.', 'wptuts-countdowner-locale' ) ) );
To reflect the name and description of our widget:
// TODO: update classname and description // TODO: replace 'wptuts-countdowner-locale' to be named more plugin specific. Other instances exist throughout the code, too. parent::__construct( 'wptuts-countdowner-id', __( 'Wptuts+ Countdowner', 'wptuts-countdowner-locale' ), array( 'classname' => 'wptuts-countdowner-class', 'description' => __( "A widget to display a countdown timer in your site's sidebar.", 'wptuts-countdowner-locale' ) ) );
Now we have this:
3. Collect Info From the User
Our widget is going to need a name and date for the event to count down (or up) to.
So, we need to create a form to be used when our widget is added to a sidebar for configuration. The WordPress Widget Boilerplate separates the HTML portion into view files for a nice, clean separation of concerns. We'll setup our variables in the method, and then the form itself in the admin view.
Here's the method. Changes for our plugin indicated with highlights.
/** * Generates the administration form for the widget. * * @param array instance The array of keys and values for the widget. */ public function form( $instance ) { // TODO: Define default values for your variables $instance = wp_parse_args( (array) $instance ); // TODO: Store the values of the widget in their own variable if ( ! empty( $instance['event'] ) ) { $event = $instance['event']; } else { $event = __( 'Event Name', 'wptuts-countdowner-locale' ); } if ( ! empty( $instance['event_date'] ) ) { $event_date = $instance['event_date']; } else { $event_date = date( 'Y-m-d' ); } // Display the admin form include( plugin_dir_path(__FILE__) . '/views/admin.php' ); } // end form
You'll note at the end of the method, there's an include
for the view. So open up /wp-content/plugins/wptuts-countdowner/views/admin.php. Add the following code into that file:
<p> <label for="<?php echo $this->get_field_id( 'event' ); ?>"><?php _e( 'Event:' ); ?></label> <input class="widefat" id="<?php echo $this->get_field_id( 'event' ); ?>" name="<?php echo $this->get_field_name( 'event' ); ?>" type="text" value="<?php echo esc_attr( $event ); ?>" /> </p> <p> <label for="<?php echo $this->get_field_id( 'event_date' ); ?>"><?php _e( 'Event Date:' ); ?></label> <input class="widefat wptuts-event-date" id="<?php echo $this->get_field_id( 'event_date' ); ?>" name="<?php echo $this->get_field_name( 'event_date' ); ?>" type="text" value="<?php echo esc_attr( $event_date ); ?>" /> </p>
Now you can refresh the WordPress Dashboard and add the widget to your sidebar, which will look like this:
Sadly, whatever you put in those fields won't save yet, so we need to modify the update
method as follows:
/** * Processes the widget's options to be saved. * * @param array new_instance The previous instance of values before the update. * @param array old_instance The new instance of values to be generated via the update. */ public function update( $new_instance, $old_instance ) { $instance = $old_instance; // TODO: Here is where you update your widget's old values with the new, incoming values $instance['event'] = strip_tags( $new_instance['event'] ); $instance['event_date'] = strip_tags( $new_instance['event_date'] ); return $instance; } // end widget
Now we have a working widget admin! You can drag the widget into your sidebar, and save the details for an event, like Christmas:
4. Showing on the Front End
Now we have event details for the countdown time, let's show it on the front end of the site in the sidebar.
/** * Outputs the content of the widget. * * @param array args The array of form elements * @param array instance The current instance of the widget */ public function widget( $args, $instance ) { extract( $args, EXTR_SKIP ); echo $before_widget; // TODO: Here is where you manipulate your widget's values based on their input fields $event = apply_filters( 'wptuts_countdowner_event', $instance['event'] ); $event_date = apply_filters( 'wptuts_countdowner_event_date', $instance['event_date'] ); include( plugin_dir_path( __FILE__ ) . '/views/widget.php' ); echo $after_widget; } // end widget
As with the admin form, we're using a view for the front end too, to keep the HTML separate. Open up your /wp-content/plugins/wptuts-countdowner/views/widget.php file, and add the following:
<?php if ( ! empty( $event ) ) echo $before_title . $event . $after_title; if ( ! empty( $event_date ) ) echo $event_date;
5. Counting Days
So we have an event and a date / time displaying now, but that doesn't give us a countdown. We need to add a little bit of code in to determine how many days between our event's date, and today's date. Because our date could be in the past or the future, we'll also need to add a suffix word to indicate which.
Here's the code we add to the front end part of the widget:
/** * Outputs the content of the widget. * * @param array args The array of form elements * @param array instance The current instance of the widget */ public function widget( $args, $instance ) { extract( $args, EXTR_SKIP ); echo $before_widget; // TODO: Here is where you manipulate your widget's values based on their input fields $event = apply_filters( 'wptuts_countdowner_event', $instance['event'] ); $event_date = apply_filters( 'wptuts_countdowner_event_date', $instance['event_date'] ); $event_date_seconds = date( 'U', strtotime( $event_date ) ); $today_date_seconds = date( 'U' ); $event_date = human_time_diff( $event_date_seconds ); $suffix = ( $event_date_seconds > $today_date_seconds ? 'away' : 'ago' ); include( plugin_dir_path( __FILE__ ) . '/views/widget.php' ); echo $after_widget; } // end widget
What we're doing there is getting the current timestamp in seconds for the event, and for today. We then get the human-readable version (i.e. 267 days). We also work out, based on whether the event date is in the past or the future, which suffix word to use.
Now we have a suffix word, we'd better add it to the view:
<?php if ( ! empty( $event ) ) echo $before_title . $event . $after_title; if ( ! empty( $event_date ) ) echo $event_date . ' ' . $suffix;
Now we have something that looks a bit more respectable and makes a bit more sense.
6. Pick a Date
It's a little ugly to have to manually type in a date, so let's add in the jQuery UI Datepicker, seeing as it's included in WordPress.
One thing that isn't included though, is the CSS for the date picker. So grab the CSS file and images directory from Helen Hou-Sandi's WP Admin jQuery UI repository on GitHub, and put them into your /wp-content/plugins/wptuts-countdowner/css/ directory.
Then we need to get WordPress to load them by modifying the boilerplate's register_admin_scripts
and register_admin_styles
methods, like so:
register_admin_scripts
/** * Registers and enqueues admin-specific JavaScript. */ public function register_admin_scripts() { wp_enqueue_script( 'jquery-ui-datepicker' ); // TODO: Change 'wptuts-countdowner' to the name of your plugin wp_enqueue_script( 'wptuts-countdowner-admin-script', plugins_url( 'wptuts-countdowner/js/admin.js' ) ); } // end register_admin_scripts
register_admin_styles
/** * Registers and enqueues admin-specific styles. */ public function register_admin_styles() { // TODO: Change 'wptuts-countdowner' to the name of your plugin wp_enqueue_style( 'wp-admin-jquery-ui', plugins_url( 'wptuts-countdowner/css/jquery-ui-fresh.css' ) ); wp_enqueue_style( 'wptuts-countdowner-admin-styles', plugins_url( 'wptuts-countdowner/css/admin.css' ) ); } // end register_admin_styles
Finally, add your jQuery code into the boilerplate's admin.js file to hook the datepicker up to the field.
(function ($) { "use strict"; $(function () { // Place your administration-specific JavaScript here jQuery('.wptuts-event-date').datepicker({ dateFormat : 'yy-mm-dd' }); }); }(jQuery));
7. Cleaning Up
The boilerplate contains a few things we haven't used in this plugin, so it'd be a good idea to lighten the load and remove them. The extras are these files:
- /css/admin.css
- /css/widget.css
- /js/widget.js
And these methods in the wptuts-countdowner.php file:
activate
deactivate
register_widget_scripts
register_widget_styles
- Also line
wp_enqueue_style( 'wptuts-countdowner-admin-styles', plugins_url( 'wptuts-countdowner/css/admin.css' ) );
from theregister_admin_styles
method
Conclusion
There you have it! A WordPress plugin based on the Widget Boilerplate that lets you show how many days until (or since) an event.
I hope you found it useful, please share your thoughts in the comments below.
Comments