MovableBlog: Related del.icio.us Links in Your Sidebar Using RSS, PHP and Magpie

Nuance 2.0

November 30, 2004

del.icio.us, for me, is not so much a way to store my bookmarks online and view others' bookmarks as it is a collaborative linkblogging tool. In this article, I detail how I created a "related links" sidebar on my personal weblog, Just a Gwai Lo (scroll down to the "Delicious" heading; the same script is used to generate a less-cluttered page of del.icio.us links). Here is, in brief, how it works: I make a link at del.icio.us, tag it—generally looking at the HTML pages of the tags I'm using, to see what I'm getting myself into—and then use the RSS feeds generated for each tag to add on a few links as, essentially, related links. If Flickr had tags inside a <dc:subject> element like del.icio.us did, I'd be spending the time writing this article making basically the same thing, except a "related photos" page. I suppose I could learn the APIs for both del.icio.us and Flickr and accomplish the same thing, but I'd rather not.

The first two lines of the script enable the RSS fetching functions from the Magpie RSS library. The line after that starts an unordered list for the links. If you'd rather skip reading the explanation in this article, you can view the source code. One day I'll put this code in my Subversion repository, which gently weeps because it is currently empty.

I should mention that the source code is the most current version of the script, and may differ slightly from what you read below.

You need the Magpie PHP RSS library. Also make sure to make the changes noted in the del.icio.us script itself.

require_once "/home/richard/rssclasses/rss_fetch.inc";
require_once "/home/richard/rssclasses/rss_utils.inc";

print "<ul>\n";

The third line tells the rest of the script what your username is:

$username = "username"; // replace with your del.icio.us username

When I was testing the script, del.icio.us was down for a few minutes, and I needed the ability to say the del.icio.us links were "unavailable at the moment". The Magpie Cookbook gives a method for cloaking warnings, so I included the following line before Magpie fetched the RSS feed.

error_reporting(E_ERROR); // cloak error messages

The next line fetches the RSS feed and puts the items into an an object.

$del = fetch_rss("http://del.icio.us/rss/".$username);

The next line simply checks to see whether the fetch was successful:

if ($del) {

Since del.icio.us shows the last 30 links that you've posted, it can get a little out of hand when you have related links on top of that, so I limit the amount of links to 5. You can experiment with the number to get the amount you're commfortable displaying.

$delitems = array_slice($del->items, 0, 5);

Starting the loop to display the items from the RSS feed:

foreach ($delitems as $item) {

The next line and following if block check to see if the date has been printed yet. If you want a different date format than, for example, "November 21st, 2004", check the PHP date codes and replace "F jS, Y" accordingly.

   $datethis = date("F jS, Y", parse_w3cdtf($item['dc']['date']));    
if ($datethis != $dateprinted) {
print " <li>";
print $datethis;
print "</li>\n";
}

Now comes the code to display your link and the description, if there is one. I like having lots of print statements because it makes debugging easier.

   print "  <li>";
print "<a href=\"";
print $item['link'];
print "\">";
print $item['title'];
print "</a>";
if ($item['description'] != "") {
print ": ";
print $item['description'];
}
print "</li>\n";

Now the fun part. The next if statement checks to see if there is a <dc:subject> element inside the item that the script is processing, which means you have tagged the link with one or more tags.

   if (isset($item['dc']['subject'])) {

If there are tags, then the script converts the string separated by spaces into an array.

     $tags = explode(" ", $item['dc']['subject']);

Now the script creates another list item in HTML, then starts a nested list within that list item.

     print "  <li>\n";
print " <ul>\n";

After starting the nested list, the script fetches the RSS feed for each of the tags in the item. The third line in thiis code block limits the related items to 2, because otherwise, if you tag your item with a lot of tags, you'll get a lot of related items.

     foreach ($tags as $tag) {
$tagrss = fetch_rss("http://del.icio.us/rss/tag/".$tag);
$tagitems = array_slice($tagrss->items, 0, 2);

Still only processing the RSS feed of one of your tags, another loop starts to process the items in that RSS feed. The second line filters out del.icio.us links created by you (after all, those links appear in the RSS feed for the tag as well) because it would just be redundant, especially if the last few links with that tag were your links.

       foreach ($tagitems as $tagitem) {
if ($tagitem['dc']['creator'] != $username) {
print " <li>";
print "<a href=\"";
print $tagitem['link'];
print "\">";
print $tagitem['title'];
print "</a>";

We're still in the second loop (that is, inside the loop for the tag's RSS feed which is inside the loop for processing the tags of your original item), and the following block...

           if (rtrim($tagitem['description']) != "") {
print ": ";
print $tagitem['description'];
}

Because you were not the original author of the related link--unless you have another del.icio.us account that you linked something using the same tag with--you can absolve yourself of some responsibility of the content (link URL, text and description) by saying who it was linked by. In this script, I had it so that it linked to the author's del.icio.us page. (It seemed only fair that if I'm syndicating their content I should link to the page from which it came.) After doing this, all the loops, except for the very first, which is of your links' RSS feed, are closed, as is the nested list.

           print " (linked by ";
print "<a href=\"http://del.icio.us/";
print $tagitem['dc']['creator'];
print "\">";
print $tagitem['dc']['creator'];
print "</a>)</li>\n";
}
}
}
print " </ul>\n";
print " </li>\n";
}


The next line stores the date of the most recent item printed, so that when it goes back to the top of the loop, it can check against the date of the next item. The original loop is closed (after all of your items are processed) and the if block is closed.

   $dateprinted = $datethis;
}
}

Remember how we had the rudimentary error checking at the beginning? The following else block just prints something more friendly than an ungly error message. Lastly, the end tag for the unordered list is printed.

else {
print "<li>del.icio.us links not available at the moment.</li>\n";
}

print "</ul>";

That's the script. Let me know if you run into any problems with it. I've been meaning to update my instructions to integrate PHP and del.icio.us using Magpie and my instructions to integrate del.icio.us using a Movable Type plugin, but instead wrote the above script.

Posted by Richard at 11:11