« Modern Lines | Main | Titanium Gold »

October 04, 2004

Style Switcher Implementation

There seems to be a few requests regarding to how the style switcher is implemented, so this entry will serve this purpose - detailing how I implemented the style switcher on the Movable Style site, including samples of source code that you can use for your own site.

The internals of this style switcher is actually quite simple, but it requires PHP running on the server side for it to work. Here are some objectives that I had when I first started:

  • Minimal client side (java-)scripting.
  • Works on every page.

Setting Up The Tree

Here's the directory structure on the webserver that I have set up for the Movable Style site. There is no database behind the styles, and everything is stored as files in directories. So all the scripts on this page depend on this set up.

  • / - Base directory for http://www.movablestyle.com/
    • archives/ - Blog entry archives
    • inc/ - PHP includes
    • styles/ - Styles archives


      • Boxed/


        • styles-site.css

      • Boxed_Green

      • Lovingrey

      • Mac_Stripe

      • ...

      • Slashdot

      • TypePad_Thin


I put all my styles into the styles/ directory, with individual style directories created inside them. In each style directory, you should always find at least the styles-site.css, which provides the CSS. For some there are also image files used by the style. If there are more than just the .css, I also created a ZIP archive titled styles-site.zip which contains all the files in that directory. For example:

$ ls styles/Slashdot
bannerbg.png  headerbg.png  styles-site.css  styles-site.zip
$ unzip -t styles/Slashdot/styles-site.zip
Archive:  styles/Slashdot/styles-site.zip
    testing: bannerbg.png             OK
    testing: headerbg.png             OK
    testing: styles-site.css          OK
No errors detected in compressed data of styles/Slashdot/styles-site.zip.

PHP Auto Prepend

I am too lazy to add a <?php import(...); ?> on every template that I have touched, so I settled for the PHP auto prepend. Here is what I have in my .htaccess in the base directory.

php_value include_path [Movable Style base directory]/inc
php_value auto_prepend_file "prepend.php"

PHP Source Code

Here is the content of prepend.php which provides functions to work out the stylesheet to use.

<?php

// Where the script can find the list of style directories.
define(STYLE_BASE, '[Movable Style base directory]/styles/');
// What the default style should be.
define(DEFAULT_STYLE, 'MovableType_Clean');

$style = $_GET['style'];
if (!$style) {
$style = $_COOKIE['style'];
} else {
setcookie('style', $style, time()+31536000, '/');
}

function get_style() {
global $style;
if (is_valid_style($style)) {
return $style;
} else {
return DEFAULT_STYLE;
}
}

function get_style_title() {
$s = get_style();
$s = str_replace('_', ' ', $s);
return $s;
}

function get_style_list() {
$result = array();
if ($d = @opendir(STYLE_BASE)) {
while ($f = readdir($d)) {
if (is_valid_style($f) && !is_hidden_style($f)) {
$result[] = $f;
}
}
closedir($d);
}

sort($result);
return $result;
}

function is_hidden_style($f) {
return file_exists(STYLE_BASE."$f/hidden");
}

function is_valid_style($f) {
return file_exists(STYLE_BASE."$f/styles-site.css");
}

function list_style() {
$list = get_style_list();
$curr = get_style();
$html = '';
foreach ($list as $r) {
$r2 = str_replace('_', ' ', $r);
$selected = ($r == $curr) ? ' selected="selected"' : '';
$html .= "<option value=\"$r\"$selected>$r2</option>";
}

return $html;
}
?>

It would take hints on what the current style should be, based on:

  • style parameter passed in through GET query string, i.e. in URL where ?style=FooBar.
  • style cookie so that current style setting can be retained across pages.
  • If neither sources above provide a valid style, then DEFAULT_STYLE will be used.

Movable Type Template Modification

Now we need to modify the Movable Type templates to use functions provided by PHP to obtain the current style.

First of all, all generated files need to be processed by PHP. That would mean the file extension should all be changed to .php, or somehow configure the Apache to filter through the default .html with PHP.

Now use the following code in the HTML head of the index/archive pages so that the stylesheet will be selected based on query string/cookie.

<link rel="stylesheet" href="<$MTBlogURL$>styles/<?=get_style()?>/styles-site.css"
      title="<?=get_style_title()?>" type="text/css" />

If you want a drop down list for a style switcher, here is an example, as implemented on the Movable Style site.

<div>Select a stylesheet to change to.</div>
<form action="index.php" method="get">
  <select name="style" onchange="this.form.submit()">
    <?= list_style() ?>
  </select>

</form>

Comment, Trackback & Search

In Movable Type, comments and trackback that brings up pop-up window are dynamically generated inside the CGI, so that PHP derivatives would not work in these templates. What I did was writing a simple MT plugin to determine the style name base on value stored in cookie. Note that in this case, MT must be installed under the same host as the blogsite in order to share the cookie, Otherwise you might need to play around cookie's domain in PHP so that CGI's in MT can see the value.

Now, put the following content into a file called mt/plugins/MovableStyle.pl

use strict;
use MT::Template::Context;
use CGI::Cookie;

MT::Template::Context->add_tag(MovableStyle =>
sub {
my %cookies = fetch CGI::Cookie;
if ($cookies{'style'}) {
return $cookies{'style'}->value;
} else {
return 'MovableType_Clean';
}
}
);

And modify your comment/traceback/search templates with the following HTML code.

<link rel="stylesheet" href="<$MTBlogURL$>styles/<$MTMovableStyle$>/styles-site.css"
      type="text/css" />

Done! Pretty simple, isn't it? :)

» Comments Dasme » October 4, 2004 08:51 AM

TrackBack URL for this entry:
http://movablestyle.com/mt/mt-tb.cgi/46

Comments

  1. » CSS Switcher from Beyond The Journey
    MovableStyle.com: Style Switcher Implementation This looks a bit complex. Is there any other tut for css switching?... [Read More]

    Tracked on October 13, 2004 10:46 PM


Post a comment





Remember Me?



Comments are moderated and may be edited or removed at the discretion of the Movablestyle.com Admins.