Extending SimplePie to Parse Unique RSS Feeds
Feb 27th in Screencasts by Jeffrey Way
A few days ago, as I prepared our Create a Slick Flickr Gallery with SimplePie tutorial, it occurred to me that we haven't posted many articles that covered SimplePie. Considering how fantastic a library it is, I think it's time to take a closer look.
We'll be looking at a more advanced feature that allows you to extend the built-in item class to allow for the parsing of complicated RSS feeds.
Hi, I'm Jeff. I'm the editor of Nettuts+, and the Site Manager of Theme Forest. I spend too much time in front of the computer and find myself telling my fiance', "We'll go in 5 minutes!" far too often. I just can't go out to dinner while I'm still producing FireBug errors...drives me crazy. During my free time, I sporadically write articles for my own personal blog. If it will keep you in the good graces of the church, follow us on Twitter.
Our Mission
If your only desire is to import the feeds of a few blogs to display on your website, you shouldn't have any trouble at all. In fact, the SimplePie.org website has a great intro screencast that will teach you exactly how to do as much. If you're unfamiliar, I highly recommend that you view it. However, from time to time, you'll come across some unique tag names. For example, while working on my personal site reboot, I determined that I'd like to display my nettuts+ videos from Blip.tv's RSS feed. Upon reviewing the feed itself, I came across tags, like: <blip:smallThumbnail>.
Now SimplePie does a tremendous job of simplifying the most common procedures. But obviously, they can't be expected to provide convenient short-cut methods for every namespace, now can they!? Of course not. I decided that this would make for an excellent screencast. So, I've created a simple example that will pull in all of the nettuts+ screencasts, and allow the for a "pop-up" video when the user chooses one.
It's a simple enough layout; but should be just perfect for demonstration purposes. Without further ado, let's begin.
Step 1: Index.php
The first step is to download SimplePie and place the "simplepie.inc" file in your "includes" folder. Next, create index.php'. Within it, paste the following basic code.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<link rel="stylesheet" href="css/default.css" />
<title>Untitled Document</title>
</head>
<body>
<div id="container">
</div><!--end container-->
<!-- begin scripts -->
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.1/jquery.min.js"></script>
<script type="text/javascript">
</script>
</body>
</html>
The only things worth noting are that we've created a wrapping "container" div, and are using Google's CDN to import jQuery. Don't worry if you're not familiar with this library; it's just a way to add a bit of frosting at the end. It's hardly essential.
Step 2: New SimplePie();
I'll be assuming that you have a basic understanding of SimplePie. If you don't, watch their introductory video first, and then return. Fortunately, there's nothing too difficult here.
Just before your doctype, add a bit of PHP.
<?php
require 'includes/simplepie.inc';
$feed = new SimplePie();
$feed->set_feed_url('feed://nettuts.blip.tv/rss');
$feed->set_item_class();
$feed->enable_cache(true);
$feed->set_cache_duration(3600);
$feed->set_cache_location('cache');
$feed->init();
$feed->handle_content_type();
?>
The first step when working with SimplePie is to create a new instance of the SimplePie class. Next, we naturally need to tell it the url of our feed (set_feed_url).
As I mentioned earlier, we'll be working with Blip.tv today. If you have your own account, click on one of your videos to visit the show page. Next, scroll down to the bottom. You'll see an RSS link within the footer. Copy that url and paste it in as a parameter.
Next, we need to set an item_class. We'll modify this section a bit later. The next three methods set up caching, the duration (in seconds), and the location of our "cache" folder. We better create that right now. Make sure that your folder structure looks similar to this.
$feed->init();
Finally, we need to initialize everything. If you don't understand this, don't worry about it too much. Just accept that it's what "gets the feed rolling".
"Init() is what makes everything happen. Period. This is where all of the configuration options get processed, feeds are fetched, cached, and parsed, and all of that other good stuff. This is called automatically if you pass a URL to the SimplePie constructor." - SimplePie Documentation
Step 3: Grabbing the Title and Description
Let's write a bit of code that will extract the title and description from our feed. Within the container div, append the following two lines.
<h1><?php echo $feed->get_title(); ?></h1>
<p><?php echo $feed->get_description(); ?></p>
Notice those easy to understand methods?! SimplePie makes these procedures a cinch. We created the $feed object at the top of our page. Remember, it's essentially a copy of the item class. To access the methods, we need to use an OOP approach. For a full list, be sure to visit SimplePie's API reference.
For the title, we're using "$feed->get_title()", and for the description, we'll conveniently use "$feed->get_description".
Step 4: The Loop
The next step is to loop through all of the items in the RSS feed.
<?php foreach($feed->get_items() as $item) : ?>
<div class="entry">
<a href="" title="">
<img src="" alt="<?php $item->get_title(); ?>" />
</a>
</div>
<?php endforeach; ?>
Lots of PHP here, but it's all relatively simple. We're using the shorthand form of a PHP loop. SimplePie supplies a "get_items()" method that will retrieve every item from the RSS feed. We then loop through each item and assign a temporary variable called $item. We can now use this new variable to retrieve specific information at the item level.
Problem
We've unfortunately hit a snag. If you'll refer back to the demo, you'll see that we want to pull in a thumbnail for each item. If we visit the url of the RSS feed, and then choose "View Source", we'll see the following: <blip:thumbnail_src>NETTUTS-WordPressForDesigners8774-306.jpg</blip:thumbnail_src>
So what do we do when SimplePie doesn't recognize a unique namespace like "blip"? The solution is to create a new class that extends the SimplePie item class.
New Class
Return to your "includes" folder and add a new file called: simplepie_blip.inc
Don't worry if you're not familiar with that file extension. We'll just be using PHP. We need a way to reference that "blip" namespace. Return to the RSS feed and once again view the source. Scroll to the top and look for something like this:
Copy this value into your clipboard. Next, paste the following code into your new .inc file.
<?php
define("SIMPLE_NAMESPACE_BLIP", "http://blip.tv/dtd/blip/1.0");
class SimplePie_Item_Blip extends SimplePie_Item
{
...
}
It's Just a Class
All we're building here is a very simple class that extends the SimplePie item class. At the top of our code, we define a constant and make it equal to the url that you just copied. We next create a new class - the name can be whatever you want. It's vital that you make sure you write "extends SimplePie_Item". This will give us access to the necessary properties and methods from the parent class.
What Do We Want?
Let's first figure out what values we need to retrieve. Take another look at the RSS feed source code.
For this simple(r) tutorial, we'll only grab three tags.
- <blip:thumbnail_src> : contains the name of our thumbnail image.
- <blip:embedLookup> : contains the url that will allow us to embed the video on our page.
- <blip:puredescription> : contains the description of the video.
Let's start by creating our thumbnail_src method. Create a new method within the Class braces.
function get_thumbnail_src()
{
$data = $this->get_item_tags(SIMPLE_NAMESPACE_BLIP, 'thumbnail_src');
return $data[0]['data'];
}
You're free to name the method whatever you like; just make sure that it's easy to understand. We begin by creating a new variable called $data. SimplePie offers a method called "get_item_tags". Remember, we're able to use this because we're EXTENDING the item class. Within the parenthesis, we paste in our constant "SIMPLE_NAMESPACE_BLIP", and then add the name of the tag that we're searching for. In this case, we want the "<blip:thumbnail_src>" tag.
What to Return?
It's a bit difficult to describe the array that we'll be returned. I recommend that you review the screencast to gain a better understanding. For the sake of simplicity, just accept that, in order to access the exact value, we must find [0]['data'] within our $data array.
That's actually all that is required. We can now begin using "get_thumbnail_src()" in the same way that we would "get_title()". Let's return to index.php and add this new method.
Find the image tag within the .entry div.
<div class="entry">
<a href="" title="">
<img src="" alt="<?php $item->get_title(); ?>" />
</a>
</div>
get_thumbnail_src()
When we call our "get_thumbnail_src()" method, it will return the filename, i.e. "NETTUTS-WordPressForDesigners8774-306.jpg". This is just the name of the image; we still need the full path. Luckily, this is easy. All Blip images will be stored here: "http://a.images.blip.tv/{filename}".
Within the source attribute of our image, add:
<img src="http://a.images.blip.tv/<?php echo $item->get_thumbnail_src(); ?>" alt="<?php $item->get_title(); ?>" />
See how easy it was to use our custom method? Now, let's return to our extended class file and create the other two methods. I won't go over these, because they follow the exact same path.
// end get_thumbnail_src function.
function get_pure_description()
{
$data = $this->get_item_tags(SIMPLE_NAMESPACE_BLIP, 'puredescription');
return $data[0]['data'];
}
function get_embed_id()
{
$data = $this->get_item_tags(SIMPLE_NAMESPACE_BLIP, 'embedLookup');
return $data[0]['data'];
}
It's important to remember that the "puredescription", and "embedLookup" tags are case sensitive. It's easiest if you just copy the text directly from the source of the RSS feed.
See if you can place these methods in their proper places on your own. As a refresher, the returned values of our methods should look like:
- get_thumbnail_src() : NETTUTS-WordPressForDesigners8774-306.jpg
- get_pure_description() : "This is a video that will teach bla bla..."
- get_embed_id : grg378cLj7EM
After inserting these methods, you should end up with something that looks like the following:
<div class="entry">
<a href="http://blip.tv/play/<?php echo $item->get_embed_id();?>" title="<?php echo $item->get_pure_description();?>">
<img src="http://a.images.blip.tv/<?php echo $item->get_thumbnail_src(); ?>" alt="<?php $item->get_title(); ?>" />
</a>
</div>
Hopefully, all of this makes sense. If not, review the screencast. At this point, your page should resemble this:
Step 5: CSS
Not too pretty, eh? Let's add an ounce of CSS. These styles don't relate to the tutorial in any way. Considering this, I won't detail each property. You're free to review the CSS file here. It's very minimalistic.
Step 6: jQuery
Just to have a bit of fun, I decided that, when the user clicks on one of the images, a pop-up video player should appear. Let's use jQuery to allow for this functionality.
$('.entry a').click(function() {
var url = this.href;
var embedString = '<embed src="' + url + '" type="application/x-shockwave-flash" width="640" height="480" allowscriptaccess="always" allowfullscreen="true"></embed>';
$('<div id="video">')
.append(embedString)
.append('<p>X</p>')
.css({
left: $(window).width() / 2 - 320,
top: '50px' })
.appendTo('body')
.children('p').click(function() { $(this).parent().remove(); });
return false;
});
Analysis
$('.entry a').click(function() {
When the anchor tag within our .entry div is clicked, run a function.
var url = this.href;
var embedString = '';
Create a variable called "url" and make it equal to the href of the anchor tag that was clicked. Remember, this href links contains the embed link. Next, create the embed tag. Truthfully, we could do something a bit more efficient here. This is the code that blip.tv provides, so it will suffice for now. You might want to look into something that's a bit more "validator" friendly in the future.
$('')
.append(embedString)
.append('
X
')
.css({
left: $(window).width() / 2 - 320,
top: '50px' })
.appendTo('body')
.children('p').click(function() { $(this).parent().remove(); });
- Create a new div element.
- Insert the embed tag that we just created (represented by the "embedString" variable.).
- Add a paragraph tag containing the letter X. This will allow the user to exit out of the video.
- Set the positioning of our video. This code just makes sure that it's centered within the container div.
- Append our new div element to the body tag. It won't show up at the bottom of the page because we've used CSS to position it absolutely. Review the CSS file for more info.
- Find that P tag - which contains the letter "X". When that element is clicked, find the #video element and remove it from the page. This is the code that gets rid of the video.
Complete
Run the page in your browser, click on an image, and you'll find that the video pops up perfectly. If the user has Javascript disabled, he or she will simply be directed to a new page that contains the embedded video.
I hope this helped you to gain a better understanding of SimplePie's capabilities. Have a great weekend...but not before Digging this tutorial. :)
- Subscribe to the NETTUTS RSS Feed for more daily web development tuts and articles.
Related Posts
Check out some more great tutorials and articles that you might like
Enjoy this Post?
Your vote will help us grow this site and provide even more awesomeness
Source Files, Bonus Tutorials and
More for $9 a month for all TUTS+
sites in one subscription.
Join Now
User Comments
( ADD YOURS )eddie February 27th
I dont use SimplePie before~
( )But i would get a try
Darren Mooney February 27th
Ah nice one, Jeff. I’ve been hoping to use SimplePie for a project soon.
Keep em comin!
( )Rijalul Fikri February 27th
Will have to try it for sure
( )Devin February 27th
very nice, didn’t css-tricks just put up something like this?
( )Snorri - Css February 27th
NICE 1
( )windir February 27th
Great! I will use this for an ongoing project! LOVE IT!
( )Darren Mooney February 27th
@ Devin – Yeah, but it was just a simple RSS mash-up screencast. Was a goodie though.
( )Ryan February 27th
Why not use simple_xml?? seems weird to me –
( )Wassim February 27th
Really liked it!
Thanks Jeff.
( )Jamis Charles February 27th
sWEET. I’ve be looking for resources on how to generate RSS from PHP for some time. Thanks a bunch.
( )UglyToys February 27th
OMG, dude. You are awesome! Search same trick on past week.
Thanks.
( )M.A.Yoosuf February 27th
its nice jeff, BTW, there was a same kind of Article released in Nettuts using simple-Pie, same but it was for flicker.
i’m suggesting better to avoid duplicates, as well as as a plus point in todays view i saw only the Modal like window. its pretty amazing, and its useful, why don’t you make How to make a Custom Modal window Tutorial?
as conclusion I’m saying better to avoid duplicates.
Yoosuf
( )crysfel February 27th
lets try!!
( )sx February 27th
Great tutorial Jeff!!!
Always good to learn new classes.
@Yoosuf: How did you miss the introduction?
“A few days ago, as I prepared our Create a Slick Flickr Gallery with SimplePie tutorial, it occurred to me that we haven’t posted many articles that covered SimplePie. Considering how fantastic a library it is, I think it’s time to take a closer look.
We’ll be looking at a more advanced feature that allows you to extend the built-in item class to allow for the parsing of complicated RSS feeds.”
( )Jeffrey Way February 27th
@sx – Thank you!
( )rob February 27th
Hi
could you please make a tutorial using simplePie and wordpress please!
thank you so much!
( )Mike February 27th
Haha. Its funny that you mention Chris right at the beginning of this tutorial. Before I Began to watch it I was like “is he trying to out do Chris or something…?”
Great tutorial man. Keep up the great for!
( )LastVid February 27th
Seems like simplexml_load_file with a foreach loop would do the trick here… is SimplePie overkill for this app?
( )demogar February 27th
This was a good and interesting video
( )Really well done Jeffrey!
Pieter February 28th
Great post. The tag-stuff is interesting.
It’s fun to work with Simplepie. Used it together with NewsBlocks (http://simplepie.org/wiki/tutorial/how_to_replicate_popurls) for a clients project.
( )klausy February 28th
@Jeffrey thanks again for this one, ive always had issues importing feeds,this will help alot on my next project..
Thanks
( )aperta February 28th
Thank you!
( )ultra49 February 28th
Thanks
( )Ryan Parman February 28th
This is a great video that I’m going to feature on the SimplePie blog as soon as I finish watching it.
When you limited the results to 20, I noticed that you did it the hard way.
You can pass a $start and $length parameter to get_items() to do it for you: $feed->get_items(0, 20);
Just thought I’d pass it along.
( )Jeffrey Way February 28th
@Ryan – Oooh, nice tip. I wasn’t aware of that one.
I’m glad to hear that you’ll be featuring it on the site; I was hoping you would.
( )Jeffrey Way February 28th
Everyone – I’ve updated the source code to reflect Ryan’s tip.
( )inkubis March 1st
nice to try….
thanks
( )Ricardo March 1st
Wow this is great!
Thanks!
I know just the place where this will be pretty pretty useful for me!
( )Bryan Kwon March 4th
Thank you so much, Jeff.
( )Mike B March 10th
Does this work with iTunes podcasts? I use Podcast maker that sends it to iTunes.
( )Gianfranco March 23rd
Is it possible to setup SimplePie to have a website displaying multiples feeds, but :
when you click on a feed “item” (permalink), instead of going to the item’s full article on the feed’s website, you dispaly the article on your own website, with your style (and of course you provide a link to the original source / item’s article on feed’s website).
Kind of, instead of that:
list of feeds > list of items > original article on feed website.
That:
list of feeds > list of items > content > (link to original article on feed website).
Thanks in advance for enlighting me.
( )Ronn0 March 25th
He doesn’t take my feed
( )Ronn0 March 25th
It’s a feed for a client, he can’t change it. It’s buildup like:
etc. etc.
( )Adam Winogrodzki April 19th
You are awesome! Search same trick on past week.
Thanks.
( )sak April 20th
Hi Jeff,
Thanks for sharing the nice article on extending the simplePie.
i am working on same kind of xml feed to get the data. i have query if you can help me out on this. here is my xml where i want to fetch the media:thumbnail value from attribute. please give me sample code of how to get that.
−
( )sak April 20th
Hi Jeff,
Thanks for sharing the nice article on extending the simplePie.
i am working on same kind of xml feed to get the data. i have query if you can help me out on this. here is my xml where i want to fetch the media:thumbnail value from url attribute. please give me sample code of how to get that.
ex -
( )alin May 13th
1. $(”)
2. .append(embedString)
3. .append(’X')
4. .css({
5. left: $(window).width() / 2 – 320,
6. top: ‘50px’ })
7. .appendTo(’body’)
8. .children(’p').click(function() { $(this).parent().remove(); });
9.
the closing div was not in the video tutorial, jquery will close this div on his own?
( )or will create a conflict with xhtml?
honey June 9th
Is it possible to use mootools instead of jquery to open up the video in a new popup like window. Tried moopop.js but it opens up in a browser like window. Also with moopop.js, it crashes when I try to open in firefox. I have used mootools.js on my page and jquery on the same page conflicts with mootools.js.
Thanks
( )topclaudy July 8th
Nice Tuto!
( )lewis July 10th
very Nice tutorial, any Idea if it can parse itune rss? thx in advance
( )Sunny Singh October 10th
This helped me a ton on my site, many thanks.
( )I even had it working the first time, that’s never happened to me.
MacFanboys November 6th
You saved me with this tut! Been racking my brain for days!
Thanks!
( )