Our site (http://en.commtap.org), uses a fair amount of JavaScript to modify how its pages are presented according to a visitor's preferences. Unfortunately it appears that a significant number of our visitors don't have JavaScript enabled in their browsers - and do not have the means to enable it - these computers are in primary schools. In this case, the alternative would be for a visitor's preferences to be processed server side when the page is being created in Drupal. This would mean that we would have to turn page caching off, slowing down the delivery of pages for everyone. The other option could be to pass a visitor's entire set of preferences around on the url - so that Drupal would cache each version - but this would create some very long and unwieldy urls.
One thing I have come up with is to arrange it so that Drupal delivers a fresh uncached page for anonymous visitors who don't have JavaScript enabled, and the cached version for all other anonymous visitors. There does not seem to be a great deal of flexibility in what you can do in controlling whether or not Drupal delivers a cached page in response to a request, however Drupal will always deliver a new uncached page if a message has been set, and I have used this idea to solve this problem.
The following function will force Drupal to deliver the next page as a fresh uncached page if a visitor can accept cookies, but the has_js cookie is not set (anything that doesn't accept cookies will get the cached page just as the more usual anonymous visitor with JavaScript enabled).
<?php
function mytheme_nojs_nocache(&$vars) {
// Make sure our dummy message never actually appears on the page:
if (!empty($vars['messages'])) {
$vars['messages'] = str_replace("<div class=\"messages nojs_nocache\">\nnojs_nocache</div>\n", '', $vars['messages']);
}
// Check if any cookie is set (i.e. can the browser accept cookies at all?), if non found,
// try to set one:
if (empty($_COOKIE)) {
setcookie('mytheme_cookie_test', 1, 0);
return;
}
// If cookies can be set, check that has_js is not set/not true:
if (!$_COOKIE['has_js']) {
// Set a dummy message (to force Drupal to deliver a new page on the next page request)
// (we will remove the message from the html before the next page gets sent to the browser):
drupal_set_message('nojs_nocache', 'nojs_nocache', FALSE);
}
}
?>
This function would be called from your theme_preprocess_page(&$vars) function in your theme. The visitor will need to have browsed through at least one generally non-cached page in their session for this to start working - I use the CacheExclude module to achieve this (excluding pages from the cache where options can be selected).