Create A Dead Simple Twitter Feed with jQuery + PHP + OAuth (Updated)

Written by Kevin Liew on 12 Apr 2016
193,191 Views • Tutorials

In this tutorial, we will be creating a jQuery script that retrieve twitter tweets from user account. It's quick and easy, come with link, hash tag, alias parser as well as time posted (calculated relatively). Most importantly, everything has a class and will be flexible to style and match your design!

This is an old post that I created long time ago, but it hasn't been updated ever since Twitter moved on from the old API. Now I decided to spend some time to fine tune it and added a layer of PHP with OAuth authentication to retrieve tweets. I also added the capability to display media for the tweet.

To retrieve tweets from user timeline, we will be using statuses/user_timeline public API from Twitter. To make the OAuth authentication painless, we're using this third party PHP-Twitter API wrapper caled Twitter for PHP.

You will need to sign in to the Twitter and register an application from the Twitter App page to get teh required consumer keys and access tokens. Remember to never reveal your consumer secrets. Click on My Access Token link from the sidebar and retrieve your own access token. Now you have consumer key, consumer secret, access token and access token secret.

We will use links/hashtag/alias script to format Tweet's hashtag, aliases. This is the screenshot of text and image tweets:

HTML

We need a simple HTML layout, linked with jQuery framework and twitter script. Also, a div with id called "jstwitter" - we will be appending all tweets from twitter server, processed it and chuck it inside.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
	<meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />
	<title></title>
	<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js" type="text/javascript"></script>
	<script src="twitter.js"></script>
</head>
<body>
	
	<div id="jstwitter">
	</div>
	
</body>
</html>

CSS

We made a quick and clean layout. However, you can style the following elements:

  • .twtr-hashtag: #abc
  • .twtr-hyperlink: hyperlink
  • .twtr-atreply: #abc
  • .time: relative time (10 minutes ago)
body {
  background:#bae0f6;
  font-size:14px;
  font-family: 'Helvetica', arial, sans-serif;
}

* {
  -webkit-box-sizing:border-box;
  -moz-box-sizing:border-box;
  box-sizing:border-box;
}

#jstwitter {
	width: 300px;
	font-size: 15px;
	color: #333333;
  margin: 0 auto;
  text-align:center;
}

#jstwitter .tweet {
	margin: 0 auto 15px auto;
	padding: 15px;
	border-radius:3px;
  background:#ffffff;
  text-align:left;
  box-shadow: 0 0 2px 1px rgba(0,0,0,0.1);
}

#jstwitter .tweet a {
	text-decoration: none;
	color: #13c9d0;
}

#jstwitter .tweet a:hover {
	text-decoration: underline;
}

#jstwitter img {
  display:block;
  margin-bottom:5px;
  max-width:100%;
}

#jstwitter .tweet .time {
	font-size: 10px;
	font-style: italic;
	color: #666666;
  display:block;
  margin-top:3px;
}

Javascript

Alright, javascript. We will divide it into 3 sections:

  • loadTweets: This is how we retrieve tweets. We use AJAX to call a PHP Twitter API wrapper which will return data in JSON format. This function retrieves and processes it.
  • timeAgo: Relative calculator from twitter.
  • ify: Convert twitter hashtag, alias, and links into hyperlinks.
JQTWEET = {
	
	// Set twitter username, number of tweets & id/class to append tweets
	user: 'quenesswebblog',
	numTweets: 5,
	appendTo: '#jstwitter',

	// core function of jqtweet
	loadTweets: function() {
		$.ajax({
			url: 'tweets.php',
			type: 'post',
			dataType: 'json',
			data: {
				q: JQTWEET.user,
				count: JQTWEET.numTweets,
        api: 'statuses/user_timeline'
			},
			success: function(data, textStatus, xhr) {

        var html = '<div class="tweet">TWEET_IMGTWEET_TEXT<div class="time">AGO</div>';

				// append tweets into page
				for (var i = 0; i < data.length; i++) {
          
					$(JQTWEET.appendTo).append(
						html.replace('TWEET_TEXT', JQTWEET.ify.clean(data[i].text))
							.replace(/USER/g, data[i].user.screen_name)
							.replace('AGO', JQTWEET.timeAgo(data[i].created_at))
							.replace(/ID/g, data[i].id_str)
              .replace('TWEET_IMG', (data[i].entities.media && data[i].entities.media.length ? '<img data-src="' + data[i].entities.media[0].media_url + '"/>': ''))
					);

				}					
			}	

		});
		
	}, 
	
		
	/**
      * relative time calculator FROM TWITTER
      * @param {string} twitter date string returned from Twitter API
      * @return {string} relative time like "2 minutes ago"
      */
    timeAgo: function(dateString) {
		var rightNow = new Date();
		var then = new Date(dateString);
		
		if ($.browser.msie) {
			// IE can't parse these crazy Ruby dates
			then = Date.parse(dateString.replace(/( \+)/, ' UTC$1'));
		}

		var diff = rightNow - then;

		var second = 1000,
		minute = second * 60,
		hour = minute * 60,
		day = hour * 24,
		week = day * 7;

		if (isNaN(diff) || diff < 0) {
			return ""; // return blank string if unknown
		}

		if (diff < second * 2) {
			// within 2 seconds
			return "right now";
		}

		if (diff < minute) {
			return Math.floor(diff / second) + " seconds ago";
		}

		if (diff < minute * 2) {
			return "about 1 minute ago";
		}

		if (diff < hour) {
			return Math.floor(diff / minute) + " minutes ago";
		}

		if (diff < hour * 2) {
			return "about 1 hour ago";
		}

		if (diff < day) {
			return  Math.floor(diff / hour) + " hours ago";
		}

		if (diff > day && diff < day * 2) {
			return "yesterday";
		}

		if (diff < day * 365) {
			return Math.floor(diff / day) + " days ago";
		}

		else {
			return "over a year ago";
		}
	}, // timeAgo()
    
	
    /**
      * The Twitalinkahashifyer!
      * http://www.dustindiaz.com/basement/ify.html
      * Eg:
      * ify.clean('your tweet text');
      */
    ify:  {
      link: function(tweet) {
        return tweet.replace(/\b(((https*\:\/\/)|www\.)[^\"\']+?)(([!?,.\)]+)?(\s|$))/g, function(link, m1, m2, m3, m4) {
          var http = m2.match(/w/) ? 'http://' : '';
          return '<a class="twtr-hyperlink" target="_blank" href="' + http + m1 + '">' + ((m1.length > 25) ? m1.substr(0, 24) + '...' : m1) + '</a>' + m4;
        });
      },

      at: function(tweet) {
        return tweet.replace(/\B[@ï¼ ]([a-zA-Z0-9_]{1,20})/g, function(m, username) {
          return '<a target="_blank" class="twtr-atreply" href="http://twitter.com/intent/user?screen_name=' + username + '">@' + username + '</a>';
        });
      },

      list: function(tweet) {
        return tweet.replace(/\B[@ï¼ ]([a-zA-Z0-9_]{1,20}\/\w+)/g, function(m, userlist) {
          return '<a target="_blank" class="twtr-atreply" href="http://twitter.com/' + userlist + '">@' + userlist + '</a>';
        });
      },

      hash: function(tweet) {
        return tweet.replace(/(^|\s+)#(\w+)/gi, function(m, before, hash) {
          return before + '<a target="_blank" class="twtr-hashtag" href="http://twitter.com/search?q=%23' + hash + '">#' + hash + '</a>';
        });
      },

      clean: function(tweet) {
        return this.hash(this.at(this.list(this.link(tweet))));
      }
    } // ify

	
};



$(document).ready(function () {
    // start jqtweet!
    JQTWEET.loadTweets();
});

PHP

Ever since Twitter moved on from REST 1.0, the most secure implementation if using server-side language because you need to specify consumer key, consumer secret key and access tokens. You need to be authenticated in order to access the API too. Thankfully, there's a lot of PHP library available to make this simple.

We're going to use Twitter for PHP. Here's the source for PHP side, a very simple implementation:

<?php

require_once 'twitter-php/twitter.class.php';

//Twitter OAuth Settings, enter your settings here:
$CONSUMER_KEY = '...';
$CONSUMER_SECRET = '...';
$ACCESS_TOKEN = '...';
$ACCESS_TOKEN_SECRET = '...';

$twitter = new Twitter($CONSUMER_KEY, $CONSUMER_SECRET, $ACCESS_TOKEN, $ACCESS_TOKEN_SECRET);

// retrieve data
$q = $_POST['q'];
$count = $_POST['count'];
$api = $_POST['api'];

// api data
$params = array(
	'screen_name' => $q,
	'q' => $q,
	'count' => 20,
  'includes_rts' => true
);

$results = $twitter->request($api, 'GET', $params);

// output as JSON
echo json_encode($results);
?>

Conclusion

No doubt, twitter is one of the hottest social media, so I hope this tutorial will able to help you to display your own tweets in your website. If you like it, please help me to spread it :) Thanks!

Demo Download
Join the discussion

Comments will be moderated and rel="nofollow" will be added to all links. You can wrap your coding with [code][/code] to make use of built-in syntax highlighter.

136 comments
thomas 13 years ago
Thanks for the tut,
I just integrated it into a wordpress theme, on the homepage.
Just have something weird, sometimes when loading the page (or reloading), the twitter feed disappears.

Could it be something coming from the floating "#jstwitter .tweet" boxes? or because i wrapped the whole twitter feed in a div?
Reply
Kevin 13 years ago
I'm having a similar problem, when I float this box the tweets don't appear ... you ever figure this out?
Reply
Kevin 13 years ago
ok figured this out, nested the jsTwitter Div in another Div that holds the float ... working like a charm, great code
Reply
lxn 13 years ago
Nice! I'd including tweet on mine blog and this tutorial is very usefu! Thank's for sharing it!
Reply
photo slideshow wordpress 13 years ago
Great tips. Now I have learned creating nice tweets. Thanks for sharing.
Reply
Jamie Graham 13 years ago
This is a great little tutorial - worked for me first try which is saying something.

Can you show us a little bit of how to integrate the Twitter Media Entities into this script? So that, if a user had included an image in their tweet using the new Twitter image feature, the image could be used in my app?
Reply
Ryan 13 years ago
This is great and super simple but I'm having the same problem as Thomas. Sometimes the tweets just don't load. Curious.
Reply
Kevin Liew Admin 13 years ago
Hi Ryan, this could be the limitation of the API. Twitter stated that it's 150 calls per IP.
https://dev.twitter.com/docs/rate-limiting
Reply
Kevin Liew Admin 13 years ago
that's weird. I can't replicate your issue. Can you setup a webpage so I can investigate this problem?
Reply
Bicho Malvado 12 years ago
Very nice tut, i'm using this in my site, but i doesn't seem to work in Opera :S ....is there a way to make it work?

Cheers
Reply
Kevin Liew Admin 12 years ago
Hi Sorry for late reply, it's fixed. What you have to do is, in twitter.js change this line (bottom):

// start jqtweet!
JQTWEET.loadTweets();

to

$(document).ready(function () {
// start jqtweet!
JQTWEET.loadTweets();
});
Reply
Meisha 12 years ago
Is there a way to get this to work in Opera by any chance? That is the only browser I cannot get it to show up in.
Reply
Kevin Liew Admin 12 years ago
Same as previous comment, what you have to do is, in twitter.js change this line (bottom):

// start jqtweet!
JQTWEET.loadTweets();

to

$(document).ready(function () {
// start jqtweet!
JQTWEET.loadTweets();
});
Reply
Timothy 12 years ago
Thanks for the code!

I was wondering if you can also load #something instead of a user?
Reply
Kevin Liew Admin 12 years ago
it's possible. You have to modify the code and adapt to the hashtag json data. This is how you get the hashtag:

http://search.twitter.com/search.json?q=%23jquery

%23jquery = #jquery
Reply
Brandon 12 years ago
can you show what this code would look like for the hashtag following?
Reply
Mike Ilz 12 years ago
Great Twitter feed! Is this ok to use on WordPress themes for resale?.. (just wanted to ask to be safe)
Reply
Kevin Liew Admin 12 years ago
Feel free to use it in any way you want :)
Reply
Danny 12 years ago
Thanks. As a learning exercise I was looking for simple way to handle twitter api with jQuery ajax call, found it all here. Nice and to the point.
Reply
Callum 12 years ago
This is fantastic! Thanks. It would be great to also add the avatar and username to the feed. I'm guessing it would be a case of adding a few lines of code to the core function of jqtweet but I'm afraid my java skills are not up to the task. Any idea how to do this?
Reply
shawn 12 years ago
awesome work, been searching for this all over, thank you!
Reply