Create WordPress Widget To Display Twitter Updates

Twitter Disc

In a previous article I explained how you can use PHP to access the Twitter APIs to get your latest Twitter updates. View this article How To Use Twitter API To Display Your Twitter Updates.

In this article I spoke about how this is a nice bit of code that can be converted into a WordPress plugin to use on your WordPress blog. The ideal place for this display will be in the sidebar of your blog.

So in this article I will finalise and show you how to convert this code into a WordPress plugin you can use to add a Twitter widget to your wordpress blog.

Widget Engine

Why Use A WordPress Widget

A widget is just a piece of code that can be used in anywhere on your blog which is defined to hold widgets.

Popular widgets used on many blogs are:

  • Subscribe to RSS feed
  • Popular Posts
  • Advertisement Areas
  • Search Box
  • Blog Categories
  • Tag Clouds

Benefits of using a widget for this functionality is that you can easily move them around to different areas of your blog such as the footer, header or sidebar.

The reasons why you would put the Twitter updates as a widget is because you are able to create a form on the widget admin screen to quickly change the username and the number of tweets you want to display. As this is a widget it will update instantly and will change the feed updates to your new settings.

The best reason to use a widget is that you can easily remove it from your wordpress blog. This may not sound like a good thing because why are you making this functionality if you want to make it easy to remove?

This is because of the limitations of using the Twitter API, like all APIs there is a limit on how many requests you can make and with twitter it is 150 requests per hour. So if you get enough traffic to your site and don’t cache your pages you will quickly run out of requests per hour. This might be a time you think about removing this functionality and replacing the Twitter feed with something else. That's why creating this functionality as a widget will mean you can quickly remove it from your sidebar.

But there is a workaround for this problem which I will explain later in this article, by using the inbuilt wordpress cache API.

folder_widget

Create WordPress Widget Holding Areas

In order to use WordPress widgets in sidebars or footers you need to register these areas to store the widgets.

First go to your functions.php page and add the code to register your sidebar to use widgets.

if ( function_exists('register_sidebar') )
	register_sidebar(array(
		'before_widget' => '<li id="%1$s" class="widget %2$s">',
		'after_widget' => '</li>',
		'before_title' => '',
		'after_title' => '',
	));

Now the sidebar has been registered you can set the sidebar.php to be dynamic and accept widgets. This is done by adding the following function to the sidebar.php

dynamic_sidebar( $index );

This has one parameter which is used to define the name of the sidebar.

Now the sidebar can be used to add widget in the location you have put the function dynamic_sidebar. All you have to do is go to the widget admin area and you can drag and drop the widgets onto the sidebar.

PHP

Creating The PHP File For WordPress Widget Code

As the sidebar has been setup to accept widgets we can now create the widget to be used by the sidebar.

Create a new PHP file, you need to add comments to the top of the php file so that WordPress can tell this is plugin.

/*
Plugin Name: Paulund Display Twitter Widget
Version: 1
Plugin URI: http://www.paulund.co.uk/create-wordpress-widget-to-display-twitter-updates
Description: Display your twitter messages in wordpress sidebar
Author: Paul Underwood
Author URI: http://www.paulund.co.uk
*/

For this widget we are going to use global variable which most of the functions are going to need to use place these under the comments.

$twitter_options['widget_fields']['title'] = array('label'=>'Title:', 'type'=>'text', 'default'=>'');
$twitter_options['widget_fields']['username'] = array('label'=>'Username:', 'type'=>'text', 'default'=>'');
$twitter_options['widget_fields']['num'] = array('label'=>'Number of links:', 'type'=>'text', 'default'=>'5');
$twitter_options['widget_fields']['update'] = array('label'=>'Show timestamps:', 'type'=>'checkbox', 'default'=>true);
$twitter_options['widget_fields']['hyperlinks'] = array('label'=>'Discover Hyperlinks:', 'type'=>'checkbox', 'default'=>true);
$twitter_options['widget_fields']['twitter_users'] = array('label'=>'Discover @replies:', 'type'=>'checkbox', 'default'=>true);
$twitter_options['widget_fields']['encode_utf8'] = array('label'=>'UTF8 Encode:', 'type'=>'checkbox', 'default'=>false);

The WordPress website has well written documentation about how to create a plugin.

Move this file into it’s own folder and upload it to your WordPress plugins folder. WordPress will look into this folder for your plugins.

This can now be used as a plugin for your WordPress blog.

Plug In

Adding functionality To Your Plugin

From the previous tutorial of How To Use Twitter API To Display Your Twitter Updates we can take this code and put it in a function to be used by the wordpress plugin.

We are going to pass in a number of parameters to this function so we can setup the twitter updates.

function twitter_messages($username = '', $num = 5, $update = true, $hyperlinks = true, $twitter_users = true, $encode_utf8 = false) {

global $twitter_options;

//Set parameter for query string
$username = 'paulund_';
$num = '10';
 
// Get the data from Twitter JSON API
$json = wp_remote_get("http://api.twitter.com/1/statuses/user_timeline.json?screen_name=$username&count=$num");
 
// Decode JSON into array
$data = json_decode($json['body'], true);
 
//Create unordered list
echo '<ul class="twitter">';
 
//Loop through all twitter tweets and display the text with the time it was created
foreach($data as $tweets){
 
    $text = $tweets['text'];
    $date = $tweets['created_at'];
 
    //Make time human readable ie. 6 hours ago
    $h_time = sprintf( __('%s ago'), human_time_diff( $time ) );
 
    echo '<li>'.$text . ' '. $h_time . '</li>';
}
 
//Close list
echo '</ul>'

}

exchange

Turn Plugin Into A Widget

Now you have a working functional WordPress plugin you need to turn this into a Widget you can easily put into the sidebar of your WordPress blog.

For the different steps of creating the widget we will add a new function which will be called on initialising the plugin, this function will create the functions to:

  1. Register it as a widget.
  2. Create The Widget Admin Area Screen
  3. Call the function to display the Twitter messages

evolution-tasks

Register Plugin As A WordPress Widget

When the widget is ran it will need to call a function which will initialise the Twitter messages function. This is done by adding a WordPress action which will be called as the widgets are setup.

add_action('widgets_init', 'widget_twitter_init');

The action will call the function widget_twitter_init, which is used to add all the functionality needed to setup the widget admin area and display the twitter messages.

Admin_min

Setup Form For Widget Admin Area

The following is going to be functions which is placed inside the widget_twitter_init function.

Create a new function which is used for the form of the Twitter widget. This is where we will collect:

  • The username to get the twitter updates
  • Number of twitter updates to get
  • Choose to display timestamps
  • Choose if to find links in the twitter updates
  • Choose if you want to display mentions
function widget_twitter_control($number) {

global $twitter_options;


		// Get our options and see if we're handling a form submission.
		$options = get_option('widget_twitter');
		if ( isset($_POST['twitter-submit']) ) {

			foreach($twitter_options['widget_fields'] as $key => $field) {
				$options[$number][$key] = $field['default'];
				$field_name = sprintf('%s_%s_%s', $twitter_options['prefix'], $key, $number);

				if ($field['type'] == 'text') {
					$options[$number][$key] = strip_tags(stripslashes($_POST[$field_name]));
				} elseif ($field['type'] == 'checkbox') {
					$options[$number][$key] = isset($_POST[$field_name]);
				}
			}

			update_option('widget_twitter', $options);
		}

		foreach($twitter_options['widget_fields'] as $key => $field) {
			
			$field_name = sprintf('%s_%s_%s', $twitter_options['prefix'], $key, $number);
			$field_checked = '';
			if ($field['type'] == 'text') {
				$field_value = htmlspecialchars($options[$number][$key], ENT_QUOTES);
			} elseif ($field['type'] == 'checkbox') {
				$field_value = 1;
				if (! empty($options[$number][$key])) {
					$field_checked = 'checked="checked"';
				}
			}
			
			printf('<p style="text-align:right;" class="twitter_field"><label for="%s">%s <input id="%s" name="%s" type="%s" value="%s" class="%s" %s /></label></p>',
				$field_name, __($field['label']), $field_name, $field_name, $field['type'], $field_value, $field['type'], $field_checked);
		}

		echo '<input type="hidden" id="twitter-submit" name="twitter-submit" value="1" />';
	}

This is the form that will be used by the user, this needs to be added to the widget admin area.

Register the Twitter Widget And Admin Form

The following function will be used to register the Twitter form and the activate the get Twitter messages function.

The control admin area will be activated by using the function wp_register_widget_control.

function widget_twitter_register() {
		
		$options = get_option('widget_twitter');
		$dims = array('width' => 300, 'height' => 300);
		$class = array('classname' => 'widget_twitter');

		$name = 'Paulund Twitter';
		$id = "paulund_twitter"; // Never never never translate an id
		wp_register_sidebar_widget($id, $name, 'widget_twitter', $class, '');
		wp_register_widget_control($id, $name, 'widget_twitter_control', $dims, '');
		
		add_action('sidebar_admin_setup', 'widget_twitter_setup');
	}

Now we need to call this function as it will be the first thing to be created.

widget_twitter_register();

Call The Function To Get Twitter Messages

The register function will then call a widget_twitter, this is the function that will be used to get the Twitter messages and actually display the output on the sidebar.

Here is where you can add any additional styling to the list. This is where you can place the standard variables of options you add before and after each widget.

function widget_twitter($args, $number = 1) {

		global $twitter_options;
		
		// $args is an array of strings that help widgets to conform to
		// the active theme: before_widget, before_title, after_widget,
		// and after_title are the array keys. Default tags: li and h2.
		extract($args);

		// Each widget can store its own options. We keep strings here.
		include_once(ABSPATH . WPINC . '/rss.php');
		$options = get_option('widget_twitter');
		
		// fill options with default values if value is not set
		$item = $options[$number];
		foreach($twitter_options['widget_fields'] as $key => $field) {
			if (! isset($item[$key])) {
				$item[$key] = $field['default'];
			}
		}
		
		echo $before_widget . $before_title . '<h3><a href="http://twitter.com/' . $item['username'] . '" class="twitter_title_link">'. $item['title'] . '</a></h3>' . $after_title;
		twitter_messages($item['username'], $item['num'], true, $item['update'], $item['linked'], $item['hyperlinks'], $item['twitter_users'], $item['encode_utf8']);
		echo $after_widget;
				
	}

WordPress Widget Admin Area

Go to your wordpress widget area and you should see your new widget to choose. You should be able to just drag this into your sidebar area.

Now you can open up the menu and type fill in the form so it will know which twitter account to get your twitter updates.

poolbird_twitter

Fixing Twitter API Limitations

As Twitter have put a fix on the amount of requests you can make in an hour if you have a large audience then you will quickly reach your limit of 150 per hour. Therefore you need to create a solution for this.

The best way to get around this problem is to cache your Twitter results using the wordpress inbuilt cache engine called transient, which allows you to temporary store information on the wordpress database and get at a later date.

As Twitter in constantly updating you don’t want to cache it for too long but you don’t want to reach your 150 request limit so a cache of 5/10 minutes will be perfect for this.

Below is an example of using the get/set transient in WordPress to display your twitter feed.

$transName = 'list-tweets'; // Name of value in database.
$cacheTime = 10; // Time in minutes between updates.

if(false === ($twitterData = get_transient($transName) ) ){
   //Get new $twitterData
   $json = wp_remote_get("http://api.twitter.com/1/statuses/user_timeline.json?screen_name=$username&count=$num");
		 
   // Get tweets into an array.
   $twitterData = json_decode($json['body'], true);

   set_transient($transName, $twitterData, 60 * $cacheTime);  
}

Code

Full Code Of Widget

/*
Plugin Name: Paulund Display Twitter Widget
Version: 1
Plugin URI: http://www.paulund.co.uk/create-wordpress-widget-to-display-twitter-updates
Description: Display your twitter messages in wordpress sidebar
Author: Paul Underwood
Author URI: http://www.paulund.co.uk
*/

define('MAGPIE_CACHE_ON', 1); //2.7 Cache Bug
define('MAGPIE_CACHE_AGE', 180);
define('MAGPIE_INPUT_ENCODING', 'UTF-8');
define('MAGPIE_OUTPUT_ENCODING', 'UTF-8');

$twitter_options['widget_fields']['title'] = array('label'=>'Title:', 'type'=>'text', 'default'=>'');
$twitter_options['widget_fields']['username'] = array('label'=>'Username:', 'type'=>'text', 'default'=>'');
$twitter_options['widget_fields']['num'] = array('label'=>'Number of links:', 'type'=>'text', 'default'=>'5');
$twitter_options['widget_fields']['update'] = array('label'=>'Show timestamps:', 'type'=>'checkbox', 'default'=>true);
$twitter_options['widget_fields']['hyperlinks'] = array('label'=>'Discover Hyperlinks:', 'type'=>'checkbox', 'default'=>true);
$twitter_options['widget_fields']['twitter_users'] = array('label'=>'Discover @replies:', 'type'=>'checkbox', 'default'=>true);
$twitter_options['widget_fields']['encode_utf8'] = array('label'=>'UTF8 Encode:', 'type'=>'checkbox', 'default'=>false);


$twitter_options['prefix'] = 'twitter';

function twitter_messages($username = '', $num = 5, $update = true, $hyperlinks = true, $twitter_users = true, $encode_utf8 = false) {

	global $twitter_options;
	
	$transName = 'list-tweets'; // Name of value in database.
    $cacheTime = 10; // Time in minutes between updates.
    
    if(false === ($twitterData = get_transient($transName) ) ){
		// Get the tweets from Twitter.
		$json = wp_remote_get("http://api.twitter.com/1/statuses/user_timeline.json?screen_name=$username&count=$num");
		 
		// Get tweets into an array.
		$twitterData = json_decode($json['body'], true);
		
		// Save our new transient.
	    set_transient($transName, $twitterData, 60 * $cacheTime);
	
    } 
		
	echo '<ul class="twitter">';
	
	if ($username == '') {
		echo '<li>';
		echo 'RSS not configured';
		echo '</li>';
	} else {
		
		if(empty($twitterData) || isset($twitterData['error'])){
			echo '<li class="follow_on_twitter">';
			echo '<a href="http://www.twitter.com/'.$username.'" title="Follow Me On Twitter">Follow Me On Twitter</a>';
			echo '</li>';
		} else {
			$i=0;
			
			foreach($twitterData as $item){
					
					$msg = $item['text'];
					$permalink = 'http://twitter.com/#!/'. $username .'/status/'. $item['id_str'];
					if($encode_utf8) $msg = utf8_encode($msg);
					$link = $permalink;
				
					 echo '<li class="twitter-item">';

			          if ($hyperlinks) { 	$msg = hyperlinks($msg); }
			          if ($twitter_users)  { $msg = twitter_users($msg); }
			          								
			          echo $msg;
              
			        if($update) {				
			          $time = strtotime($item['created_at']);
			          
			          if ( ( abs( time() - $time) ) < 86400 )
			            $h_time = sprintf( __('%s ago'), human_time_diff( $time ) );
			          else
			            $h_time = date(__('Y/m/d'), $time);
			
			          echo sprintf( __('%s', 'twitter-for-wordpress'),' <span class="twitter-timestamp"><abbr title="' . date(__('Y/m/d H:i:s'), $time) . '">' . $h_time . '</abbr></span>' );
			         }          
                  
					echo '</li>';
				
					$i++;
					if ( $i >= $num ) break;				
			}
		}
	}
	
	echo '</ul>';
	
}

// Find links and create the hyperlinks
function hyperlinks($text) {
    $text = preg_replace('/\b([a-zA-Z]+:\/\/[\w_.\-]+\.[a-zA-Z]{2,6}[\/\w\-~.?=&%#+$*!]*)\b/i',"<a href=\"$1\" class=\"twitter-link\">$1</a>", $text);
    $text = preg_replace('/\b(?<!:\/\/)(www\.[\w_.\-]+\.[a-zA-Z]{2,6}[\/\w\-~.?=&%#+$*!]*)\b/i',"<a href=\"http://$1\" class=\"twitter-link\">$1</a>", $text);    
    
    // match name@address
    $text = preg_replace("/\b([a-zA-Z][a-zA-Z0-9\_\.\-]*[a-zA-Z]*\@[a-zA-Z][a-zA-Z0-9\_\.\-]*[a-zA-Z]{2,6})\b/i","<a href=\"mailto://$1\" class=\"twitter-link\">$1</a>", $text);
        //mach #trendingtopics. Props to Michael Voigt
    $text = preg_replace('/([\.|\,|\:|\¡|\¿|\>|\{|\(]?)#{1}(\w*)([\.|\,|\:|\!|\?|\>|\}|\)]?)\s/i', "$1<a href=\"http://twitter.com/#search?q=$2\" class=\"twitter-link\">#$2</a>$3 ", $text);
    return $text;
}

//Find twitter users
function twitter_users($text) {
       $text = preg_replace('/([\.|\,|\:|\¡|\¿|\>|\{|\(]?)@{1}(\w*)([\.|\,|\:|\!|\?|\>|\}|\)]?)\s/i', "$1<a href=\"http://twitter.com/$2\" class=\"twitter-user\">@$2</a>$3 ", $text);
       return $text;
}     

// Create the twitter widget
function widget_twitter_init() {

	if ( !function_exists('register_sidebar_widget') )
		return;
	
		$check_options = get_option('widget_twitter');
		
		  if ($check_options['number']=='') {
		    	$check_options['number'] = 1;
		   	 	update_option('widget_twitter', $check_options);
		  }
  
	function widget_twitter($args, $number = 1) {

		global $twitter_options;
		
		extract($args);

		// Each widget can store its own options. We keep strings here.
		include_once(ABSPATH . WPINC . '/rss.php');
		$options = get_option('widget_twitter');
		
		// fill options with default values if value is not set
		$item = $options[$number];
		foreach($twitter_options['widget_fields'] as $key => $field) {
			if (! isset($item[$key])) {
				$item[$key] = $field['default'];
			}
		}
		

		echo $before_widget . $before_title . '<h3><a href="http://twitter.com/' . $item['username'] . '" class="twitter_title_link">'. $item['title'] . '</a></h3>' . $after_title;
		twitter_messages($item['username'], $item['num'], true, $item['update'], $item['linked'], $item['hyperlinks'], $item['twitter_users'], $item['encode_utf8']);
		echo $after_widget;
				
	}

	//Output the user form
	function widget_twitter_control($number) {
	
		global $twitter_options;

		$options = get_option('widget_twitter');
		if ( isset($_POST['twitter-submit']) ) {

			foreach($twitter_options['widget_fields'] as $key => $field) {
				$options[$number][$key] = $field['default'];
				$field_name = sprintf('%s_%s_%s', $twitter_options['prefix'], $key, $number);

				if ($field['type'] == 'text') {
					$options[$number][$key] = strip_tags(stripslashes($_POST[$field_name]));
				} elseif ($field['type'] == 'checkbox') {
					$options[$number][$key] = isset($_POST[$field_name]);
				}
			}

			update_option('widget_twitter', $options);
		}

		foreach($twitter_options['widget_fields'] as $key => $field) {
			
			$field_name = sprintf('%s_%s_%s', $twitter_options['prefix'], $key, $number);
			$field_checked = '';
			if ($field['type'] == 'text') {
				$field_value = htmlspecialchars($options[$number][$key], ENT_QUOTES);
			} elseif ($field['type'] == 'checkbox') {
				$field_value = 1;
				if (! empty($options[$number][$key])) {
					$field_checked = 'checked="checked"';
				}
			}
			
			printf('<p style="text-align:right;" class="twitter_field"><label for="%s">%s <input id="%s" name="%s" type="%s" value="%s" class="%s" %s /></label></p>',
				$field_name, __($field['label']), $field_name, $field_name, $field['type'], $field_value, $field['type'], $field_checked);
		}

		echo '<input type="hidden" id="twitter-submit" name="twitter-submit" value="1" />';
	}
	
	function widget_twitter_setup() {
		$options = $newoptions = get_option('widget_twitter');
				
		if ( $options != $newoptions ) {
			update_option('widget_twitter', $newoptions);
			widget_twitter_register();
		}
	}
		
	
	function widget_twitter_register() {
		
		$options = get_option('widget_twitter');
		$dims = array('width' => 300, 'height' => 300);
		$class = array('classname' => 'widget_twitter');

		$name = 'Paulund Twitter';
		$id = "paulund_twitter"; // Never never never translate an id
		wp_register_sidebar_widget($id, $name, 'widget_twitter', $class, '');
		wp_register_widget_control($id, $name, 'widget_twitter_control', $dims, '');
		
		add_action('sidebar_admin_setup', 'widget_twitter_setup');
	}

	widget_twitter_register();
}

add_action('widgets_init', 'widget_twitter_init');

Conclusion

Now you have learnt how to create your own wordpress plugin and turn this functionality into a WordPress widget. What else can you use as a WordPress widget?

Advertise here

Comment