Building my own Twitter badge with RSS

Building my own Twitter badge with RSS Thumbnail Image

This week Nettuts published a screencast on how to use PHP to parse through RSS feeds and display data from them. At the same time I also noticed that this fix to make a W3C valid twitter badge, had stopped working for an unknown reason.

So I figured it would not be terribly difficult to hack the NETTUTs tutorial to make my own Twitter badge with PHP by reading the RSS feed that Twitter provides.

The Function

Here is the code for the function I wrote. It uses Curl instead of file_get_contents. After a little research file_get_contents requires allow_url_fopen = ON in the php.ini file, Which as this and this will tell you is a security risk>

Switching from file_get_contents to Curl wasn’t hard after a simple Google search turned up this post and it worked like a charm.

So here is the function I wrote by mashing up these two tutorials and a few extra if statements.

Update

My friend Aaron Parecki commented here about how I could improve this script with a few lines of RegEx code to simplify searching for twitter usernames (@) and links (http://). Its whole lot less code and a whole lot easier. You can read his addition to this here.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
<?php
function DisplayTwitterFeed($feed_url, $num=10) {
 
$ch = curl_init("$feed_url");
	curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
	curl_setopt($ch, CURLOPT_HEADER, 0);
	$data = curl_exec($ch);
	curl_close($ch);
 
	$x = new SimpleXmlElement($data);
 
	echo "<ul class='twitter'>";
 
	$i = 0;
 
	foreach($x->channel->item as $entry) {
        	if($i == $num) break;
			$i++;
 
		//get the content and cut out the first word which is always @whatever
		$tweet = $entry->title;
 
		$tweet = explode(' ', $tweet);
 
     	$tweet = implode(' ', array_slice($tweet, 1, 140));
 
		$tweet = explode(" ", $tweet);
			echo "<li>";
 
			foreach ($tweet as $words)	
 
				if ($words[0] == "@") {
					echo "<a href='http://twitter.com/" . substr($words, 1) . "'>" . $words. "</a> ";
				} elseif (substr($words, 0, 7) == "http://") {
					echo "<a href='". $words . "'>" . $words. "</a> ";
				} else {
					echo $words." ";
				};
 
			};
 
			echo "</li>";
 
	};
 
echo "</ul>";
?>

Starting from the top. We define a function and pass it two variables, our Twitter RSS URL which you can find here.

Get your twitter RSS feed here.

Get your twitter RSS feed here.

The second variable will tell the function how many tweets to display.

After defining the function I dropped in the Curl code from here.

$ch = curl_init("$feed_url");
	curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
	curl_setopt($ch, CURLOPT_HEADER, 0);
	$data = curl_exec($ch);
	curl_close($ch);

From what I have read this starts the curl session and fetches the data from the RSS feed and writes it to the $data variable. Next comes a bit of code from the NETTUTs tutorial.

	$x = new SimpleXmlElement($data);

From my research SimpleXmlElement turns XML data into easy to use arrays in PHP. So now we have a variable $x that is an array that contains the data we passed to it from our RSS feed that we can use as a normal array.

echo "<ul class='twitter'>";
 
	$i = 0;
 
	foreach($x->channel->item as $entry) {
        	if($i == $num) break;
			$i++;

This snippet will make a second variable that will control how many tweets we display using and if statement and the break command. This also starts the foreach segment that will look through our array and pick out our tweets.

Looking at our feed

It took me a little while to figure out exactly how to move through the RSS feed and get out the data we need. If you look at the source code for the RSS feed it looks like this.

<item>
    <title>graphfixpunk: i cant believe how many people are willing to pay for help on in my basic HTML/CSS class</title>
    <description>graphfixpunk: i cant believe how many people are willing to pay for help on in my basic HTML/CSS class</description>
    <pubDate>Wed, 29 Oct 2008 01:17:33 +0000</pubDate>
    <guid>http://twitter.com/graphfixpunk/statuses/979843077</guid>
    <link>http://twitter.com/graphfixpunk/statuses/979843077</link>
  </item>

if you remember the foreach statement about we started with $x and then moved to channel $x->channel and then went into item $x->channel->item and then we executed everything in the foreach statement for every item in the channel.

Back to the code

So what this code does is it fetches the content of the tweet.

$tweet = $entry->title;
 
$tweet = explode(' ', $tweet);
 
$tweet = implode(' ', array_slice($tweet, 1, 140));

Then $tweet is exploded where every word in the string will become its own word in an array. Then implode will compress that array back into a string starting from 1 (skipping 0 which is always @username)

So What that did was get the content of out tweet and cut out the first word.

So what about links?

Up until now everything was fairly easy we could just echo $tweet and stop there but then we wouldn’t have any links which the default twitter badge shows. After a lot of searching on Google and the PHP manual I found substr which lets you use parts of strings without altering the string.

$tweet = explode(" ", $tweet);
			echo "<li>";
 
			foreach ($tweet as $words)	
 
				if ($words[0] == "@") {
					echo "<a href='http://twitter.com/" . substr($words, 1) . "'>" . $words. "</a> ";
				} elseif (substr($words, 0, 7) == "http://") {
					echo "<a href='". $words . "'>" . $words. "</a> ";
				} else {
					echo $words." ";
				};
 
			};
 
			echo "</li>";

For starters we will explode $tweet again so we have an array that contains all the words in our tweet. Then we start a LI element to contain the tweet.

This is where it gets confusing. Start another foreach loop. This loop will check every word to see if the first character is equal to “@” and if it is echo an anchor tag that links to twitter.com/the_word.

If the first character is not “@” then it checks if the first seven characters in the word and if they are equal to “http://” then we echo an anchor that links to whatever the word is.

If both of those tests fail then it just echos the word with a space afterward. This foreach statement will run through this check for every word in a tweet and check for links and echo these statements back.

Lastly close your foreach and echo a close to your LI, end the foreach you started at the top of the script, and end the UL and your done.

Implementation

I had some problems getting this to work out of Wordpress default functions.php file so I made my own user-functions.php and added this code to my header.

<?php include_once (TEMPLATEPATH . '/user-functions.php'); ?>

Then just call the function where you want your twitter list to appear and pass it the url for your feed and the number of tweets to display.

	<?php DisplayTwitterFeed("http://twitter.com/statuses/user_timeline/15374455.rss", 5); ?>

So why is this better then the twitter badge?

The default twitter badge uses script tags which will not display when a user has Javascipt disabled (a little over 10% of my visitors). This code will show up no matter what and still displays links and names of tweeters.

Comment with questions and problems.

14 Comments