Supercharging CSS, Part 2: Themes

Previous: GZipped and Cached CSS

It is a reasonably common requirement--or at least it has been at least in my professional experience--to run several sites off that are very similar and indeed have virtually identical functionality. The usual reason for doing this is that different clients either want to integrate the functionality you provide into their own service offerings or a number of companies become "virtual resellers". There are two general approaches to doing this:

  1. Have separate installations that need to be separately maintained; or
  2. Use the same installation of code where the code is clever enough to act differently for whichever site it is running based on the request.

(1) leads to a lot of code repetition and generally maintenance becomes harder as you may need to modify and/or deploy a bunch of identical of near-identical changes. It is tempting to dismiss this approach out of hand but it does have its place: every condition in your code complicates your code and changes meant for oen site can potentially regress other virtual sites so the code can be cleaner this way. The rule of thumb is that if sites are more different than similar then this approach might be appropriate. That is obviously a subjective test.

The other more common approach is for the code to behave differently depending on what site the request is serving. This approach is particularly appropriate when sites are more similar than different. The obvious discriminator is the fully-qualified hostname of the site. I will usually end up with some common code that is executed on every PHP page that might go something like this:

<?php
if ($_SERVER['SERVER_NAME'] == 'www.example.com') {
  define('SITE_NAME', 'example');
} else if ($_SERVER['SERVER_NAME'] == 'www.myhost.com') {
  define('SITE_NAME', 'myhost');
} else {
  die("Unrecognized host name $_SERVER[SERVER_NAME]");
}
?>

Of course this is a simple example. The configuration might be more dynamic, possibly database-driven and there is quite likely to an awful lot more default values than these that are used (eg correct contact information, homepage content, header and footer files, copyright notices, terms and conditions, menu items and structure and so on).

So instead of identifying the "bundle" of CSS files by a supplied parameter, we simply change it to do it by username.

$bundles = array(
  'www.example.com' => array(
    'reset.css',
    'superfish.css',
    'example.css',
  ),
  'www.myhost.com' => array(
    'reset.css',
    'superfish.css',
    'myhost.css',
  ),
);

$site = $_SERVER['SERVER_NAME'];
if (!isset($bundles[$site])) {
  error_log("css.php: Unknown bundle '$site' requested");
  exit;
}

This logic can be as simple or complex as desired. For example, the "site" GET parameter (via rewrite) can be used in conjunction with the server name.

Alternatively, you could even implement user themes this way. The user could select the theme they're interested in. The link_css() function would return the correct URL to ask for that theme and css.php could then return the right bundle of CSS for that theme.

The possibilities are really endless.

Next: CSS Variables

0 comments:

Post a Comment