Making dynamic static pages

Published:

UPDATE: I changed how this works and blogged about it. I wanted my home page to reflect what was going on in my life, or at least what content I was generating. There's the concept of a lifestream floating around at the moment, but I was happy just to have a few sources (a couple of blogs, my bookmarks, my twitters and my flickr stream) shown, split out my source. The catch was I wanted to do it without implementing a web service to back it.

If you want to pull content from a bunch of different servers without writing any server-side code your only options are Flash and JSON. They're both ways of getting around the web security model that's protected us for so long. Flash is kind of complicated, requires proprietary, expensive tools to work with while JSON comes for free. The idea behind JSON is that we can use the browser's tag to load a script from another serve that contains data encoded as JavaScript data structures rather than code.

A few key services like Flickr and del.icio.us offer JSON versions of their feeds, but most do not. In steps FeedBurner who in January added a JSON version of the feeds they serve, and since you can ask FeedBurner to host any feed you please we can use them as our high-availability, standardizing, caching feed proxy. I\'d already set up FeedBurner for this blog, so I just added feeds for my LiveJournal and twitter accounts and looked up how to get access to the JSON feeds for my Flickr and del.icio.us accounts.

When you call a JSON script you can often pass in the name of a callback function to be called when the data is returned. I wrote a simple one to process a JSON response from FeedBurner and turn some of the most recent items into HTML list items:

var max_items = 3;
var target = null;
var filter = null;
function fb(o) {
  if (!target) return;
  for (var i=0; i<o.feed.items.length && i<max_items; i++) {
    var item = o.feed.items[i];
    var li = document.createElement('li');
    var a = document.createElement('a');
    if (!item.title) item.title = item.date;
    if (filter) item.title = filter(item.title)
    a.appendChild(document.createTextNode(item.title));
    a.setAttribute('href', item.link);
    li.appendChild(a);
    target.appendChild(li);
  }
}
The function depends on a couple of external variables that are set before the JSON feed is called. They are target, the DOM object to append the list items to and filter an optional function to post-process titles. I had to add filter since my twitter feed comes back a little weird.

Getting the most recent posts from this blog into a bullet list is now pretty straight-forward:

<ul id="ianloic-list" />
<script type="text/javascript">
target = document.getElementById('ianloic-list');
</script>
<script type="text/javascript"
src="http://api.feedburner.com/format/1.0/JSONP?uri=ianloic&callback=fb">
</script>
Getting my LiveJournal in was identical and twitter just required me to write a filter function to chop up the title a little and do some unescaping. For some reason the twitter feed is both HTML entity encoded and JavaScript string escaped when I get it back from FeedBurner.

Flickr and del.icio.us each require some custom code since I want to handle each of them specially. For del.icio.us I link to the tag pages of each tag on each bookmark and for Flickr I embed a thumbnail for each image. Take a look at the source code of ian.mckellar.org to see how that's done or drop me if you'd like more explanation.