I've restructured my website, and changed the backend engine, because it's What I Do. Jonathan Hitchcock, another webpage, another thesis, another bot, another blog.
In this entry, I discuss how themable websites *should* be structured, and what I've done for this site.
I've abandoned the old
mod_layout+
XSLT method of skinning my website, because it didn't really work.
XSLT relies on everything being XML, which means I have to write pure
XHTML 1.0. This is fine, since I try my damnedest to do that anyway, but sometimes it doesn't pan out, and then instead of failing gracefully, I get weird XSLT errors everywhere. The thing I like about XSLT is that it gives complete separation of content and form, or rather, of meaning and presentation. That is, you give XSLT an XML file that contains a description of what your site
means, and it turns it into something pretty. You'd give it something like this:
<site>
<heading> My heading </heading>
<body>
<leftpanel>
<item> I am online </item>
<item> Click to go home </item>
</leftpanel>
<main>
My site, hope you like it.
</main>
</body>
</site>
As you can see, this shows what each bit actually
is ("this is the left panel, this is the heading"). This would get converted into some HTML, full of <div> and <h1> and suchlike, which loses something of the
meaning of the site - the difference between a right panel and a left panel is now all in where it is placed. That's fine for those two, since that's the difference between right and left, as well, but if I had "main table of contents" and "page specific links" instead of "left panel" and "right panel", then I would lose that meaning when it got converted into almost identical HTML with merely a presentational difference.
This is also the main idea behind
CSS: HTML must just become a bunch of "div" statements with associated classes ("<div class='maintable'>", "<div class='pagespecific'>"), which are then rendered by the correct CSS to be pretty. However, it rarely turns out that way - HTML is still full of presentation. The
CSS Zen Garden does kind of provide a counter-example to this claim, but viewing the source is always a scary process on those pages.
XSLT is just too hectic for anything smaller than a massive content-system that will be viewed in ten different media, I think. So, for now, one must settle for a happy medium - leave most formatting to the CSS, and try to keep the HTML as meaningful but formless as possible, and wait for the
W3C to make everything better.
In addition to the XSLT, I'd like to lose mod_layout, too, since it's not perfect - I'd ideally like to be able to make lists of which files to layout, and which files not to layout, and specify defaults by directory. I know that you can do it with <FilesMatch> and LayoutIgnoreURI things, but it's very kludgy. So far, I'm doing fine, and I can't think of a better way to skin an entire site just yet. I don't want to have to include code in every page on my site - this would require that they are all PHP files, which adds to the processing load. Again, I could use
SSI (Server Side Includes) in HTML files, but that just means nasty CGI processing, and is just messy. It also ignores the point that I don't
want to have to include code in every page on my site - I want to drop a page in and have it themed nicely. One method that I briefly considered was virtual directories: have a hidden index.php (I'd have to do some mod_rewrite stuff for that probably), which does the skinning, and takes all the rest of the URI as asking for a specific file, and just whips that in. It's an interesting way of doign it - similar to the way
Nevow and other non-Apache, non-filesystem-based webservers decide how to serve files.
Let me summarise those thoughts:
Need a way to skin entire site
- Could include code in every file:
- Including PHP code in every file that skins it means lots of processing
- Including SSI CGI code in every file is just ugly
- I don't want to put code in every file, I want it to be drop-in
- Could use just one file that has skinning code, and uses virtual directories, mod_rewrite, etc, to include the rest of the site into the skin
- mod_layout automatically applies a layout to an entire site - that's what it's for
- It's not perfect, I'd like a finer grained control, but it works
Anyway, regardless, what I'm doing now is, I feel, rather nice. The blogging software I use,
Serendipity, has a nice template system (you can see it on the right if you're viewing this from the actual blog, and not RSS). I examined their code, and worked out how the templating system works, and I've incorporated it into the rest of the site.
Unfortunately, part of their system involves a layout.php file, which gets include()'d by PHP - this generates some HTML which CSS is later applied to. I can't use the layout.php that comes with each skin, because it has lots of calls to the Serendipity API, to suck in the sidebars, and the content, and so on. In theory, I could duplicate the API in my own code, but that seems overboard. I may as well just use the blog for my entire site, or something. Anyway, my solution turned out to be a rather nasty kludge involving a special case. Almost all of the templates use a table to format their HTML - only one of them uses <div> tags with CSS placement. So, in my code, I checked which template was being used, and created <div>s for the one, and used a table for the rest. It's a special case, and isn't perfect, but it works for now, so screw you all.
This relates back to what I said about HTML containing some of the form, and not just the meaning. The blog should generate non-formatted, meaningful HTML, and the template should be nothing but a bunch of CSS that gets applied. I designate this system "The counter-counter-example to the counter-example of the CSS Zen Garden".
Anyway, I use mod_layout to suck in a container.php file that does some stuff like storing page-hits in a database, setting some global variables (like one that contains the base URL for my site, and so on) (a lot of this stuff was taken from the web maestro Russell himself), and then generating HTML, sucking in the page being viewed at the right point.
The nice thing about my site, however, is the CSS it uses. The URL for the CSS I use on my pages is
http://vhata.rucus.net/include/css.php. This is a script that looks in Serendipity's own database, to work out what template it is using, and uses that one. The theme changer on the side in my main site is also one I wrote, to duplicate the functionality of Serendipity's theme changer plugin (which plugs heavily into the serendipity API, and thus can't be used directly).
As a result, my entire site looks exactly like my blog, and changing the theme in one of them will cause the theme to be changed in the rest. The current theme is stored in the
Session, so it will go away when you go away, and next time you visit, you'll be back to my default theme, but that's your
tough tackies.
Comments
Post new comment