Build a PHP Twitter Widget


Today I will be showing you how to use cURL to get your Twitter status and cache it into a file on your server. This file will then be read with JavaScript and displayed on the web-page. Before we start you can view a demo and download the final files below:

Live Demo

The widget will have the following file structure

File structure

API Limit

Twitter has an API limit (currently 150 calls per hour) so its best to use your username/password to make sure that you will get a successful response. If you don’t (as far as I know) Twitter will use the API calls that are for everyone with your IP/Servers IP. This means that if other people on your server are also using data from twitter (that requires an API call), it will start to give an error saying that you have used up your API limit very quickly.

Making the widget

Caching and HTML

function twitterCapture() {
        // Set your username and password here
        $user = 'twitter_username'; // Twitter Username
        $password = 'xxxxxxxx'; // Twitter Password

        $tw = curl_init("{$user}.json"); //grabs the JSON format of your timelines
        curl_setopt($tw,CURLOPT_TIMEOUT, 30); // Timeout (for when Twitter is down)
        curl_setopt($tw,CURLOPT_USERPWD,$user . ":" . $password); // Uses your username and password
        curl_setopt($tw,CURLOPT_RETURNTRANSFER,1); // returns
        $json = curl_exec ($tw); // Executes the cURL and puts it into the varible
        return $json; // returns what was grabbed
$cachefile = 'cache/twitterCache.json'; // the location to your cache file
$cachetime = 10 * 60; // set the cach time 10 * 60 (1 hour)
	// if the file exists		// if and the time it was created is less then cache time
if ( (file_exists($cachefile)) && ( time() - $cachetime < filemtime($cachefile) ) ) {
// script will not use the cached version
}else{ // the file didn't exist or is old
	ob_start(); // turn on the output buffering 
	$fp = fopen($cachefile, 'w'); // opens for writing only or will creat it's not there
	fwrite($fp, twitterCapture()); // writes to the file what was grabbed from the previouse function
	fclose($fp); // closes
	ob_end_flush(); // finishes and flushes the output buffer

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "">
<html xmlns="">

	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
	<title>Little Twitter Widget</title>
		<!-- Start of CSS -->
	<link rel="stylesheet" type="text/css" href="css/reset.css" />
	<link rel="stylesheet" type="text/css" href="css/main.css" />
		<!-- Start of JS -->
	<script type="text/javascript" src="js/jquery-1.4.js"></script>
	<script type="text/javascript" src="js/main.js"></script>	
<div id="twitter_widget_top" class="center" ></div><!-- The top of the widget -->
<div id="twitter_widget_body" class="center"> <!-- The body wrap -->

	<div id="twitter_widget_tweet"> <!-- The tweet area -->
		<div id="twitter_movement"> <!-- To position the icon reletive to -->
			<a id="twitter_icon" href=""></a> <!-- Twitter icon -->
			<div id="twitterWrap"> <!-- The blue area -->
				<div id="twitter">	<!-- The main twitter data -->
					<noscript>JavaScript must be on to view tweets</noscript> <!-- Incase no js -->
					<p class="tweet">Loading...</p> <!-- The Tweet -->
					<p class="created_at"></p> <!-- Date created -->
			<p class="clear"></p> <!-- Clear the floats -->
		<a href="" class="previous tweetNav"></a><!-- Next button -->
		<p class="follow_me">Follow me - <a href="" class="screen_name"></a></p> <!-- Follow me link -->
		<a href="" class="next tweetNav"></a> <!-- Pre button -->
		<p class="clear"></p>
<div id="twitter_widget_bottom" class="center"></div><!-- Bottom of widet -->
<p class="info">Join my <span class="followedNumber"></span> followers - <span class="user_name"></span></p>

This will check if the cache file exists and then how old it is. If its older than  how long we want to leave before getting a new copy then will run the function to grab the new copy of the your twitter stream in JSON format. This is then written to your server in the cache file.


@charset "UTF-8";
/* CSS Document */
.clear{clear: both;}
.push{height: 30px;}
/* END */
*{margin: 0; padding: 0;}
html{ position: relative;}
body{font-family: Helvetica, Verdana, Arial, sans-serif; width: 100%; height: 100%; background: #1E202A;color:#3494E5;}
.center{margin: 0 auto;}
a{text-decoration:none;color:#4AA1EF; overflow: hidden}
a:hover{color: #3D658E;}
/* END */
#twitter_widget_top{background: url(../images/top.jpg) top left no-repeat; width: 475px; height: 30px;margin-top:81px; } /*  Top of widget  */
#twitter_widget_body{background: url(../images/body.jpg) left repeat-y; width: 475px;} /*  BODY  */
#twitter_widget_bottom{background: url(../images/bottom.jpg) bottom left no-repeat; width: 475px; height: 21px; } /*  foot  */
#twitter_icon{background:url("../images/twitter_icon.jpg") no-repeat scroll center bottom transparent;height:50px;margin-left:30px;position:absolute;top:33%;width:50px;}
#twitter_icon:hover{ background-position: top center;} /*  Move icon on hover  */
#twitterWrap{    /*  Don't show overflow and set a width  */
 overflow: hidden;
 width: 350px;
 float: right;
 background: #1E202A;
 margin: 20px 20px 0;
 border: 1px solid #062333;
 -moz-border-radius: 5px;
 -webkit-border-radius: 5px;
#twitter_movement{position: relative;} /*  To align icon to  */
.tweet { /*  The Tweet  */
font-family:"Lucida Grande",Verdana,Arial,sans-serif;

.next{background:url("../images/arrows.jpg") no-repeat right top transparent;float:right;height:14px;margin-right:20px;margin-top:10px;width:21px;}
.next:hover{background-position: right center;} /* Next button  */
.previous{background:url("../images/arrows.jpg") no-repeat left bottom transparent;float:left;height:14px;margin-left: 103px;margin-top:10px;width:21px;}
.previous:hover{background-position: left center;}

.created_at {display:block;font-size:12px;font-style:italic;padding-right:20px;text-align:right;}


To get the twitter status we will use the javascript library jQuery, as this makes it a lot easier. We will use the $.getJSON to grab our cached file.

$(function() {
$.getJSON('cache/twitterCache.json', function(data) { // get the file and put in var "data"

// 		Add information about the user
	$('.followedNumber').html( data[0].user.followers_count); // follow count
	$('.screen_name').html( data[0].user.screen_name); // screen name
	$('.statuses_count').html(data[0].user.statuses_count); // amount of tweets
	$('.user_name').html(data[0]; // username
	// defult variables
	var totalAmount = "", 	// total amount of items
		moveOut = "",		// If we are moving in or out the animation
		moveIn = "",		// If we are moving in or out the animation
		current = 0,		// Set the current to 0
		$i = 0;				// Set i to 0 
$.each(data, function(){ // for each of the "data"
	totalAmount = $i; // set the varible total amount to i
	$i++; // plus one to i
	clicked(current);  // run the function to grab the first item

	$(".next").click(function(){ 			// when next is clicked
		if ($(this).hasClass('active') ){ 	// if it's active
			current = current + 1;			// set current to + 1
			moveOut = "+"; 					// make the move out animation correct
			moveIn = "-";	 				// same with move in
			clicked(current); 				// run the function and pass in current
		}; 									// no else, so nothing will happen if we click when not active

	$(".previous").click(function(){ 		// almost the same as above
		if ($(this).hasClass('active') ){
			current = current - 1;			// minus one from the tcurrent
			moveOut = "-";			
			moveIn  = "+";
//	Time function from the Twitter Blog JS file
function relative_time(time_value) {
  var values = time_value.split(" ");
  time_value = values[1] + " " + values[2] + ", " + values[5] + " " + values[3];
  var parsed_date = Date.parse(time_value);
  var relative_to = (arguments.length > 1) ? arguments[1] : new Date();
  var delta = parseInt((relative_to.getTime() - parsed_date) / 1000);
  delta = delta + (relative_to.getTimezoneOffset() * 60);

  if (delta < 60) { 
    return 'less than a minute ago';
  } else if(delta < 120) {
    return 'about a minute ago';
  } else if(delta < (60*60)) {
    return (parseInt(delta / 60)).toString() + ' minutes ago';
  } else if(delta < (120*60)) {
    return 'about an hour ago';
  } else if(delta < (24*60*60)) {
    return 'about ' + (parseInt(delta / 3600)).toString() + ' hours ago';
  } else if(delta < (48*60*60)) {
    return '1 day ago';
  } else {
    return (parseInt(delta / 86400)).toString() + ' days ago';

	function clicked(current){ // when clicked function runs
		// get the width to be able to slide the tweet area
		var tweetAreaWidth = $('#twitterWrap').width();
		// fade out the time it was created
		$('.created_at').animate({"opacity": "0"}, 400); // fade out the date
		$('.tweet').animate({"right": moveOut +  tweetAreaWidth + "px"}, function(){ // move the .tweet div left/right then
			$('.tweet')	.html( data[ current ].text  ); // add the next tweet
			var time = relative_time( data[ current ].created_at ); // get the next date
			$('.created_at').html(time);	// put data into useable format
			var tweetAreaHeight = $('#twitter').height(); // get the height of the tweet area now its got the tweet inside
			$('#twitterWrap').animate({"height": tweetAreaHeight + "px"}, function(){ // change the tweet height to the new div
				$('.tweet').css({"right":  moveIn + tweetAreaWidth + "px"}).animate({"right": 0}); // move in the tweet
				$('.created_at').animate({"opacity": "1"}, 500); // fade in the date
// dealing with the click buttons
		$('.tweetNav').removeClass('inactive').addClass('active'); // remove inactive from all buttons and add active
		if(current == totalAmount){ // if current is equal to the total amount make the next button inactive
		if(current == 0){
		$('.inactive').animate({"opacity": "0.3"}, 1000); // make inactive buttons fade out
		$('.active').animate({"opacity": "1"}, 500); // made active buttons fade in
		$('.tweetNav').click( function(){ return false; }); // return false
	}; // end of clicked function
});// end of json

This should now work, a great way to see how to access the elements that are returned is using FireBug as this lets us see the name of the json elements and what is nested in them.

Firebug example

I hope that you have found this interesting and now have a working animated twitter widget.

Gemstone rings are the most coveted accessory items to date. Also, LusterForever earrings are a must to try on.

Be Sociable, Share!

Written by Alex

My name is Alex Bor and I am currently a full time student. I have been building websites for about 4 years and love to build sites that will take advantage of new techniques (such as AJAX and CSS3) to make them both look nicer and be more user friendly. You can view my website or follow me on Twitter.


13 Responses to “Build a PHP Twitter Widget”

  1. Mohammed S. Alnasiri Says:

    March 23rd, 2010 at 10:14 am

    What an amazing lesson ! Thank you so much

  2. ITキヲスク | 2010年3/21~3/27の週間ブックマーク Says:

    March 28th, 2010 at 12:00 am

    [...] Build a PHP Twitter Widget | Brenelz Web Design Solutions [...]

  3. Web Dev Tutorials 1# | Booto'Blog Says:

    April 5th, 2010 at 6:48 pm

    [...] Build a PHP Twitter Widget By Alex, March 23rd, 2010 Site: Brenelz [...]

  4. Gabriel Esquivel Says:

    May 1st, 2010 at 10:28 pm

    Awesome ! thank you

  5. 10 Essential PHP Code Snippets You Might be Looking For | DevSnippets Says:

    May 4th, 2010 at 4:02 am

    [...] tutorial will teach us how to use cURL to get your Twitter status and cache it into a file on your server. [...]

  6. Build a PHP Twitter Widget | PHPprogramá Says:

    May 4th, 2010 at 4:59 am

    [...] Čítať ďalej originálny článok Komentáre (0) k článku “Build a PHP Twitter [...]

  7. 10 Essential PHP Code Snippets You Might be Looking For « qeqnes | Designing. jQuery, Ajax, PHP, MySQL and Templates Says:

    May 7th, 2010 at 2:00 am

    [...] tutorial will teach us how to use cURL to get your Twitter status and cache it into a file on your server. [...]

  8. chris Says:

    June 30th, 2010 at 1:03 pm

    Can you explain how to do this in Flash AS3?

  9. Brett Widmann Says:

    December 21st, 2010 at 9:04 pm

    This is a great tutorial! Everything works and looks great.

  10. Jack Nolan Says:

    January 31st, 2011 at 4:21 pm

    My sister told me about this site just yesterday. Great blog you’ve got!

  11. Steven Says:

    June 16th, 2011 at 9:04 pm

    A very interesting article and the code is lovely. I will try to work out
    the widget ASAP.

  12. theTMO Says:

    June 2nd, 2012 at 12:12 pm

    God Bless you man.

  13. Caching and displaying @rsc_ne_scotland Twitter feed JISC CETIS MASHe Says:

    June 4th, 2012 at 12:44 am

    [...] the Build a PHP Twitter Widget post by Alex Bor I came up with the following code to cache the json and rss for our Twitter [...]

Leave a Reply

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

connect with me!