Kiosk, an exercise in templating

Larry Garfield's picture

Earlier this week I checked in Palantir's latest module, Kiosk. It's a simple little module, and I was rather surprised to find the name still free, but it actually shows off some interesting tricks.

Kiosk was developed for the Art Institute of Chicago, one of Palantir's long-time clients. As part of a recent project, we were setting up dedicated web sites for temporary exhibition at the museum such as this one for Winslow Homer. Those web sites needed to be accessible to the outside world fully branded as part of the Art Institute, but the exhibition gallery itself also has a number of "kiosk" computers set up where museum-goers can get more information on the artist and his history. Those kiosk computers do not need to be branded, and in fact needed to not have the main navigation header; it's a kiosk computer, and the browser shouldn't leave that one mini-site.

The solution we developed was the Kiosk module. Kiosk allows a site administrator to set arbitrary IPs to be in "kiosk mode". Alternatively, an administrator can also set a long-life cookie (one year) on a computer, through the admin interface, to flag tht computer as a kiosk.

The rest is fairly simple. In Drupal 5, it requires adding a single line to _phptemplate_variables() in the theme layer to set an additional template variable, $kiosk. In the template, then, it's trivially easy to do the following:

<?php if(!$kiosk) : ?>
  <!-- put various navigation stuff here -->
<?php endif; ?>

And poof, no more navigation on selected computers. (In Drupal 6, we'll be able to add that variable to all templates straight from the module. Stay tuned.)

Well, OK, not quite. That works fine right up until you enable page caching. All the kiosk computers are anonymous users, of course, so they would get the cached version of a page, which probably includes the navigation. Or heaven forbid if a kiosk computer views a given page first and the cached version is missing the navigation, then a normal user comes along and views the page. The solution is to do all sorts of weird and crazy things with them caching system so that the page cache for kiosk pages is separate from the cache for normal pages. (A huge thank-you to Earl "Merlin the amazing" Miles for pointing me in the right direction here.)

First, in the install script we create a duplicate cache table named {kiosk_cache_page}. Its structure is identical to any other cache table. Then in hook_init(), we grab the $db_prefix global variable and add a special prefix to the page_cache table, if we're in "kiosk mode". That way, if a request comes in from a kiosk computer Drupal uses kiosk_cache_page as the page_cache table. If not, it uses the normal cache_page table. No muss, no fuss, and both the kiosk systems and the rest of the world keep working smoothly.

There are two catches with this method, however. One, it does break aggressive page caching. Two, clearing the page cache does not clear both caches. Instead, we clear the kiosk page cache routinely on cron. That means there may be a delay in changes propagating to the kiosk site, but not more than a cron-run's worth. In most cases that should be perfectly acceptable.

Give it a whirl, report any bugs you find, and if you're in Chicago and like water colors then stop by the Winslow Homer exhibit. It's a Drupal site, don'tcha know. :-)

Tags: