ClearSilver を Apache のフィルタモジュールとしてインプリメントしてみた
これまでもちらほらと ClearSilver という名前を聞いたことがあったんですが,YAPC::Asia での ikebe さんの発表でさらに興味を持ちました。
mod_livedoor_page.so
Inside Livedoor 2006-2007 - PDFへのリンクなので注意
- http://www.livedoor.com/
- use ClearSilver Template engine.
- top-page is not changed so frequently.
- top-page has simple data structure only.
- so we use C for top-page.
興味を持ちましたというか,キーくやしい(←何が?)となったので,自分でも ClearSilver を使った Apache モジュールを書いてみました。ソースはこちら。
実はググったら id:bonar さんがとっくに mod_clearsilver なるものを作ってたんで一瞬戦意が萎えかけたんですが,id:bonar さんはテンプレートファイルにたいする content handler として作ってらっしゃったので,filter として作ってみよう,と。
filter として作ると何がうれしいか,ですが,一言でいうと他のコンテンツハンドラと競合しないことです。つまり HDF コンテンツ自体は静的ファイルなり CGI なり PHP なりなんなりで出力して,それをテンプレートにあてはめることができる。ぶっちゃけ,X-SendFile みたいな使い方ができます*1。
<Location /cs_test> Options +ExecCGI AddHandler cgi-script cgi SetOutputFilter CLEARSILVER </Location>
みたいな設定をしといて,
<html><body> <p>My name is <?cs var:html_escape(MYNAME) ?></p> </body></html>
のようなテンプレートを用意しつつ
#!/usr/bin/perl print {*STDOUT} <<'END_DATA'; Content-Type: text/html X-CSF-Template: test.tmpl MYNAME = dayflower END_DATA
なる CGI を実行すると,
<html><body> <p>My name is dayflower</p> </body></html>
のように返ります。「X-CSF-Template」というカスタムヘッダを返すと BODY を HDF として解釈し,テンプレートに当てはめて出力するんだけど,そのカスタムヘッダがないと内容をそのままパススルーするです。
そんな仕様だと static なコンテンツが用意できないじゃんという奴は mod_asis と併用してください。というのはあんまりにむごいので「CSF_DefaultTemplate」という Apache 用設定ディレクティブも用意してあります。
filter として作ったといいつつ実はテンプレートハンドラ / HDF ハンドラとして使えるようにも作ってあります。わかる人ならソースを読めばわかる,と書いて突き放しておきます。
TODO は CGI Kit compatible な GET / POST DATA 等からの HDF Auto Generation あたりかなぁ。環境変数だけは ENV という HDF 変数に渡されるようにしてます。
参考になった URL
- 井上(さん)の日誌 - Apacheの話-
- Apache httpd のソース
- 特に modules/generators/mod_asis.c (一番シンプルだと思う)
- 特に modules/filters/mod_include.c
- APR / APR-Util のドキュメント / ソース
- 上記でも挙げた mod_clearsilver - ClearSilverのテンプレートルールを強制的に - bonar note
- ClearSilver C API つーか,ヘッダ / ソース嫁
まとめ
- 実は ClearSilver には Python / Perl*2 / Ruby bindings が用意されてるのでそれ使え
- Perl 系だと id:spiritloose さんが Perl binding を使ったモジュールをいくつか書いていらっしゃるのでテンプレートエンジンとして使うならそれらのモジュールを使えば吉
Fedora とかだと clearsilver-devel は静的ライブラリを提供してるくらい軽量ライブラリで,まるで Lua みたいだなとか思いながら作ってました。HDF の構造って Lua のテーブルに似てるし。
あと,ClearSilver じゃないけど Apache モジュールまわりでちょっと作ってみたいものとか思いついたんで,とっかかりとしてはよかったかな,と。