Advertisement

Building a Countdown Timer Widget

by
Student iconAre you a student? Get a yearly Tuts+ subscription for $45 →

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@domain.com)

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:

Figure-01

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:

Figure-02

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:

Figure-03

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:

Figure-04

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.

Figure-05

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 the register_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.

Advertisement