先日このブログで公開したばかりの、「ライブドア事件」専用トラックバック・ステーションであるが、毎回ページが開かれるたびにデータベースにアクセスする仕組みで作ったのだが、そんな作りのままではトラフィック増には耐えられない。そこで、良く出来たブログ・サービス(例えばMT)の様に、変更があったときに(つまり、トラックバックが送られてきた時に)、データベース上のデータからHTMLページを生成しておき、閲覧時にはそれを返すように変更することにした。
その作業を進めているときに、この手法の一つの欠点に気が付いた。MovableType がしているように、ヘッダーも含めた全HTMLページを生成するようにしておくと、その中にスタイルシート(CSS)へのリンクを埋め込むことになるので、スタイル(見た目)が固定化されてしまうのである。これでは面白くない。そこで、複数のスタイルシートを用意しておき、閲覧時に動的に結び付きを決められるようにする方法を幾つか考えてみた。
案1.ページ全体ではなく、HTMLの一部だけを生成しておき、PHPを使って動的にスタイルシートとの結び付けをする。
案2.HTMLではなく、PHPを生成しておき、それを使って動的にスタイルシートとの結び付けをする。
案3.HTMLの一部だけを生成しておき、prototype.js を使ってスタイルシートと結びついた親ページにそれを読み込んでくる。
案1と案2は既にやり方を知っているので、あえて案3の方法でやってみることにした。prototype.js では一度遊んでみたかったので、丁度良い。すると、親ページ(最初にブラウザーがロードするページ)はこんな感じになる。
<html>
<HEAD>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<link rel ="stylesheet" href ="listview1.css" type="text/css" />
<script src="prototype-1.4.0.js"></script>
<script>
function load() {
var myAjax = new Ajax.Updater('main', 'cache/livedoor1.html',
{method: 'get',
requestHeaders: ['If-Modified-Since','Wed, 15 Nov 1995 00:00:00 GMT'] });
}
</script>
</HEAD>
<BODY onload="load()">
<div id="main">
<div style="width: 100%; text-align: center">Loading...</div>
</div>
</BODY>
</HTML>
こんな形で作った親ページを、スタイルシートごとに複数用意しておけば(listview1.css の部分だけを変更すれば良い)、ブラウズ時にはサーバー側のスクリプトを走らせることなく、同じHTMLテキスト(このサンプル場合は cache/livedoor1.html)を異なったスタイルで見せることができるのである。サンプルとして、二つの異なるスタイルシート(listview1.css、listview2.css)と結びつけたサンプルを下に貼り付けたので参照していただきたい。
listview1.css を使って表示したもの
listview2.css を使って表示したもの
「何で同じHTMLなのにこんなに異なる表示が出来るんだ?」と疑問に思う方は、それぞれのCSSファイルを参照してみると良い。XSL/XMLによる view/data の分離と違って、分離が完璧ではないので view の自由度は限られるが、CSS/HTML を分離するだけでもかなり面白いことが出来ることがこの例を見ても良く分かると思う。
昨晩はこれが IE と Firefox 上でうまく動いたので、「クライアント側でのHTMLとCSSの動的結びつきに成功。これで色々と面白いことができる!」と喜んで寝たのだが、朝、Mac上のSafari からアクセスしてみて、がっくり。漢字が文字化けしてしまうのだ。サーバー上で生成しているHTMLファイルも親ページもどちらもUTF-8でセーブしてあるので、本来ならうまく行くはずなのだが、なぜか文字化けしてしまうのだ。
少し調べたところ、Safari は親ページが UTF-8 であることを認識しておきながら、Ajax.Update() で取得した文字列を UTF-8 と正しく認識してくれないようである(原因は不明…もし心当たりのある方がいたら、コメントをいただけるとありがたい)。そこで、少し乱暴な手段だが、サーバー側で生成する HTML ファイルの先頭に UTF-8 であることを示すBOM(EF、BB、BF)を付けてみたところやっとちゃんと動いてくれた。BOMを利用しているのは Windows ばっかりだと思っていたが、Safari に BOM を認識するコードが入っているとは少し驚きだ。
ということで、「ライブドア事件」専用トラックバック・ステーションも無事にアップデート終了。いたって簡単なプロトタイプだが、色々と勉強になった。