Scalable style switching with Dojo widgets

February 2, 2007

For a surprising number of years now, Paul Sowden’s elegant JavaScript stylesheet switcher has been the state of the art in changing the look and feel of websites on the fly. However, and with no disrespect to him whatsoever, there are reasons why this type of purely front-end solution may not easily scale up to a very complex production site like Renkoo.

For one thing, Paul’s solution is only intended to switch the stylesheet — not, for instance, any style-specific graphics used on the page. You can of course use background images for everything, as they so memorably do on CSS Zen Garden… but honestly as an old-school LAMP person rather than a designer I find it an unnatural way to work.

More importantly for us, our pages are composed of dozens of Dojo widgets — each of which can potentially have its own stylesheets (applied with templateCSSPath) and images. We needed a solution that could ripple down to this very fine-grained level with a minimum of rewriting code and a maximum of overall site performance.

Therefore we turned to Apache HTTP server, specifically its mod-rewrite module. As every dev knows, the lower-level the solution to a given problem, the faster it generally is. Instead of loading your whole page and all its attendant stylesheets, then calling a JavaScript function to process through the DOM picking out the link nodes, then changing the display based on preference order expressed in a cookie — we decided it would be easier to just use the power of URL rewriting to make sure you only get the stylesheets and images you need in the first place.

Let’s use a concrete sample Dojo widget from Renkoo: the Add a Friend widget. It looks like this in the various styles:




The great thing is that no matter which of our skins you’re using, or whether you’re applying the style via the Dojo method (templateCSSPath) or normal link tags in the parent page — our markup calls for the same CSS stylesheet:


The stylesheet directories are laid out thusly:


Now we will apply the following Apache rewrite rules:

RewriteEngine On
RewriteCond %{HTTP_COOKIE} browse_skin=([a-z]+)
RewriteRule /stylesheets/select/(.*) /stylesheets/%1/$1 [R,L]
# Else
RewriteRule /stylesheets/select/(.*) /stylesheets/default/$1 [R,L]

For those of us who don’t think in regex, this simply means that if the requesting browser has a cookie named “browse_skin” set AND is asking for a file in the “/stylesheets/select” directory, Apache will attempt to serve up a file of the same name from the directory “/stylesheets/[cookie value]” instead. We can use the exact same system with images.

This system should in theory deal with HTTP caching perfectly, resulting in flawless trickle-down through our system as soon as someone changes their cookie. Alas, there is no such thing as perfection on the web. Due to a five and a half year old bug in Mozilla — which exists in direct contravention of RFC 2616 — Mozilla-based browsers illegally cache the URL of image requests even if caching has been contraindicated by the server.

Practically speaking, this means that Camino- and Firefox-wielding Renkoo users will have to shift-reload each page once after setting a new skin preference… until the bug is fixed. The system should work perfectly for users of IE 6 or 7, and Safari.

Renkoo terminal skin -- My Invites view

To see Renkoo’s new skin switching system in action, go to your Renkoo profile page and choose an alternate skin now!

For bookmarkers among us: Save to and Digg this Digg it!!

One Response to “Scalable style switching with Dojo widgets”

  1. […] You probably know that the Dojo widget system is amazingly flexibly and will let you quickly modify not only the style of a widget, but also it’s DOM using templates. Our friends at Renkoo have gone one step further to show how a little mod_rewrite can be used to theme Dojo widgets on the fly! […]

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: