2

On one of my production sites I wrote a jQuery stylesheet switcher. It drops a cookie when a selection is made and uses php to select the corresponding stylesheet on pageload which overrides styles. All is great until I enable performance caching mode, whereby the cookie is ignored on each pageload. Obviously this isn't the desired effect and I can see why this is occuring: being that the pages are cached and no longer truly dynamic with respect to loading what's seen as a 'dynamically' changing stylesheet. You can change the stylesheet however upon returning to a page the initial style is applied. Just for reference I have coded the php into each page template (page-front.tpl.php and page.tpl.php) and the javascript is located in my scripts.js. The php is basically just a couple of if else statements.

Due to a large volume of traffic I have to enable caching on the site, however ideally would like to retain this style-switcher functionality. Is there a method of making an exception to the caching rule for this or will I have to disable the switcher? Would packing it into a module help?

Thanks in advance :)

2

I think you have have a hard time doing this with caching, since you want to create two versions of the same page.

I haven't tried this, but it should be possible to let your style.css not be an actual css file but a drupal callback that returns the styles based on the cookie. You would need to include the "stylesheet" as you would do styles for IE. You wouldn't be able to cache this, but if you really need to performance, you could do it in a php file and skip the drupal bootstrap.

An alternative option would be to let the js itself execute the styles, based on the cookie.

None of these options are ideal, but they should work.

|improve this answer|||||
  • 1
    googletorp is right in saying it is complicated since you need to create 2 versions of the same page. I had a similar issue with cookies and page cache. My solution was inspired by the [Mobile Tools][1] module and it is basically extending cache.inc by means of a custom module, then updating settings.php with: $conf['page_cache_fastpath'] = FALSE; $conf['cache_inc'] = 'path/to/my/module/my_module_cache.inc'; Then use hook_boot() to redirect to the appropriate page. [1]: drupal.org/project/mobile_tools However, executing the styles based on cookie is better and easier. – zerolab Mar 8 '11 at 11:25
  • Your first answer here seems to be the most viable.. would I be making the callback in the theme's template as a preprocess function? Not sure how to go about it :S, will read up a bit. Enabling the cache while retaining the style switcher functionality is definitely the overall objective here. – Storsey Mar 8 '11 at 13:33
  • 1
    @Steve: You have to make a small module for the job. – googletorp Mar 8 '11 at 14:38
2

Would it be possible to create only one version of the page? Include ALL the styles on every page (probably not ideal, but not the end of the world unless they're huge), and then use JavaScript to, say, add a body class depending on the value of the cookie?

Alternatively I like googletorp's idea of the stylesheet being a callback and not a .css file.

|improve this answer|||||
  • this seems like an elegant quick fix (which is what i'm after until I have more time to develop another solution).. however when changing page the default colour scheme will flash until the javascript loads? That's why I currently use php to ascertain the cookie value prior to page load.. correct me if i'm wrong :) – Storsey Mar 8 '11 at 13:17
2

Using a cookie to select a cache_page variant using memcache: http://drupal.org/node/942914. We use this for GeoIP targeting.

Using a cookie to select a mobile theme if the user is on a mobile device: http://drupal.org/node/361832#comment-4110568. Don't use this, gave some help out at one of the local SeaDUG meetings.

|improve this answer|||||

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.