It’s easy to think that the relative-time style of “this comment was written 15 minutes ago” is incompatible with caching. How are you supposed to cache something if the text changes every minute? Static pages with JavaScripts, that’s how!

I put together a new mini app for our new status site yesterday that needed exactly this technique. I wanted the content of the application to be entirely page cached, so it would withstand the onslaught if the terrible should happen and we need to redirect all trafic to the status site.

I also wanted the relative time style, especially since it’s timezone independent and you don’t want people to think you’ve been down for two hours when it’s really only been twenty minutes because they did the timezone conversion wrong.

It looks like this:

37signals status site screenshot

To make this trick work, I embed the time stamp for a given entry in the DOM as a custom attribute that I can query for conversion like this:

<li>
  <span time="Feb 05, 2009 15:30:00 GMT">09:30 AM CST (15:30 GMT)</span> /
  The aliens came out of no where and took Basecamp!
  We're trying to hunt them down now. Stay tuned while we bring the lasers online.
</li>

I only want to convert the entries from today into relative time. The entries from yesterday and before should just use the specific time-only style. This means looking for just the span’s inside li’s from the ul with the class “today”. They’re then converted when the document is loaded with this function:

convert_all_times_from_today_to_words: function() {
  $$('.today li span').each(function(e) {
    e.innerHTML = this.time_ago_in_words_with_parsing(e.getAttribute('time'));
  }, this);
}

The function uses a simple DateHelper JavaScript class that mimicks the DateHelper in Rails.

This technique can be used for things other than just dates. You could imagine a cached page where you wanted the name “David Heinemeier Hansson” replaced with the text “You” if there was a match.

It’s a great way around otherwise cache-busting requirements.