PukiWikiデフォルトスキンの変なところ

友人が「設置したWikiのデフォルトスキンの装飾が何故か無効になってて困ってる」みたいな事を言っていた。
その人はGGD2Wikiの管理やってる人なんですが、彼がテスト用に設置したPukiWikiを見ると、たしかに装飾っぽいものがさっぱりない。どうやらCSSが一切適用されていないようだ。
ちなみにそのレンタルサーバサービスはここ

PukiWikiのスキンシステム

PukiWikiはスキンセットを切り替えて、デザインをガラッと変えられるようになっている。
しかし、サーバに設置するプログラムのスキンシステムというものは、その仕様を理解するのがめんどくさいっていう印象がある。BBSnoteのスキンシステムの影響かな…。あれは、適用は簡単だけど加工が困難だった。
PukiWikiのスキンは、skinフォルダの中にセットがフォルダ単位で収納するようになっていて、設定ファイルでどのフォルダのセットを使うか指定するようになっている。思っていたよりもとっつきやすく、すっきりした仕組みだった。まだ加工はした事がないのでその辺は未知。

デフォルトスキンのCSS

デフォルトスキンのCSSが適用されないという話だけど、iridなどの追加スキンのCSSはちゃんと適用された。
じゃあこれらにどういう差があるのか、とりあえずページのソースを覗いて、CSSを指定している部分を見てみると…
デフォルトスキンは、


irid(iridwire)は


見事に違う。iridは、CSSファイルを指定している。ごく普通のやり方だ。
一方、デフォルトはCSSPHPで動的に生成している。pukiwiki.css.phpというphpスクリプトに、CSSデータを作らせてる。この辺がくさい。
ブラウザで直接、そいつにアクセスしてみた。http://〜/skin/pukiwiki.css.php?charset=Shift_JIS&media=printをアドレスバーに入れたわけ。
すると、改行が一切されていないCSSの内容が映し出された。…つーか広告が入っちゃってるよ!! そりゃまともに機能しないよ!

生成されるCSSに広告が入る対策

どうもこのレンタルサーバは、BODYタグの最初と最後のところに広告を挿入するようにしているそうなので、それを逆手にとって、pukiwiki.css.phpの最後に

/* 

 */

CSSのコメント欄を追記し、その中にBODYタグを書く。こうすりゃあ、広告がコメントアウトされる範囲の中に挿入されるので、CSS的に無害になってくれるはずだ! どれどれ! うん! 変化なし!! なんでだーーーーーーーーーーーーー!

MIME

なんでダメなのか…そういえば改行が一切なくなって表示された事が気になる。また、広告が挿入されるということは、そのデータがHTMLとしてサーバから送られている事になる。いわゆるMIMEっていう、ファイルタイプ情報がイカれてるんじゃないか?
pukiwiki.css.phpの内容の頭の部分↓

// Send header
header('Content-Type: text/css');
$matches = array();
if(ini_get('zlib.output_compression') && preg_match('/\b(gzip|deflate)\b/i', $_SERVER['HTTP_ACCEPT_ENCODING'], $matches)) {
	header('Content-Encoding: ' . $matches[1]);
	header('Vary: Accept-Encoding');
}

よくわからないが、頭の方で、「これはCSSファイルって事にしといてくださいよー」って書いてあるらしいことはわかる。
PukiWiki的にはこれがうまく作用すればCSSがバッチリ適用されるはずってことか。
Firefox拡張機能Live HTTP headersを使うと、サーバから送られてきたデータのファイルタイプが確認できる。それを試してみた。Live HTTP headersのウィンドウを表示しながらWikiを表示すると、以下のようにヘッダー情報が並ぶ。

http://〜/skin/pukiwiki.css.php?charset=Shift_JIS&media=print

GET /〜/skin/pukiwiki.css.php?charset=Shift_JIS&media=print HTTP/1.1
Host: s1.muryo-de.etowns.net
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; ja; rv:1.8.1.8) Gecko/20071008 Firefox/2.0.0.8
Accept: text/css,*/*;q=0.1
Accept-Language: ja,en-us;q=0.7,en;q=0.3
Accept-Encoding: gzip,deflate
Accept-Charset: Shift_JIS,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
Referer: http://〜/
Cache-Control: max-age=0

HTTP/1.x 200 OK
Date: Tue, 23 Oct 2007 01:06:06 GMT
Server: Apache/1.3.33 (Unix)  (Vine/Linux) mod_layout/3.2 mod_gzip/1.3.26.1a mod_ssl/2.8.22 OpenSSL/0.9.7d
X-Powered-By: ModLayout/3.2
Cache-Control: no-cache
Keep-Alive: timeout=15, max=89
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: text/html

上の塊が送った内容。つまりリクエストで、下の塊は返事、レスポンスか。一番下の行に、これはHTMLですっていう風に書いてあるな…。

IEではこれで解決

ちなみに、上記のコメントアウト戦法を駆使した結果、Firefox2.0.0.8では相変わらずCSSが適用されなかったが、IE6で表示すると、CSSはちゃんと適用された。
調べによると、IEはファイルタイプを、ファイルの内容で自動で判断するようになっているから、とのこと。
なんかこういう処理はセキュリティ的に怪しいみたいな記事も見たけど…とりあえずIEのみ対応!じゃ困る。

サーバ管理に問い合わせ

なんかもうこれはサーバサイドの問題っぽいから、なんでちゃんと動かないんだみたいなメールを送って、数回やり取りしたところ、「普通のCSSファイル置くんじゃダメかしら」みたいな返事が来た。
根本的な解決になっていない気がして、最初何言ってんだこいつみたいに思ったけど、よーーく考えてみれば、ページの表示毎にCSSを動的生成するって、すげー非効率なやり方なんじゃ?って考えになってきた。

動的生成の内容と目的

じゃあ、わざわざPHPで生成しているのはなんでよ?と思い、pukiwiki.css.phpの内容をざーーーっと見てみたら、

a:link {
<?php	if ($media == 'print') { ?>
	text-decoration: underline;
<?php	} else { ?>
	color:#215dc6;
	background-color:inherit;
	text-decoration:none;
<?php	} ?>
}

こんな記述があちこちにあった。$mediaっていう変数が「print」だったら、こういう装飾にして、そうじゃなかったらこっちの装飾を使いますよーっていう処理だ。多分。
全体に目を通したけど、PHPでの処理は全部「$mediaっていう変数が『print』だったら」だった。
これが何をしているのか、装飾の内容と「print」って言葉から想像すると、PukiWikiは、印刷モードの時に装飾を印刷向けに切り替える機能を持っていて、それをこの動的生成CSSで実現しているみたいだ…。

結局

全ページにわたって、表示するたびにCSSを生成するのはきっと非効率だし、それで得るものも少ないみたいだから、CSSについてはもう、pukiwiki.cssみたいな静的ファイルをアップロードしてそれにリンクすればいいやっていう結論になった。
とはいえ、PHPが指定するファイルタイプが無視される問題はほったらかし。
この記事を書いている最中に、「はて、RSSはちゃんと機能するのか」と思いながらRSSフィードを取得しようとしたら、やっぱりHTMLとして出力されてしまった。