毎秒1000リクエスト を捌く超高速CMS「adiary」
2006/07/19(水)スケルトンのカスタマイズ
この記事はVer2以前のものです。Ver3は無関係です。
skeltonを直接カスタマイズしたいという要望があるようなので、カスタマイズの仕方を説明します。スケルトンカスタマイズにはプログラム的知識が多少必要になります。
※2007/01/24 大幅に加筆しました。バージョンアップ時の手間を考えた場合、_main, _sidebarスケルトンの変更はあまりお勧めしません。「詳細デザイン」+トラストモードで済む場合はそちらを検討してください。
スケルトンディレクトリ diary.skel/
adiaryの機能はほぼすべてこの中に納められています。adiaryのスクリプトに対する引数
adiary.cgi?diary_edit
であれば、diary.skel/diary_edit.html が呼ばれます。カスタマイズしたい機能をみつけたい場合は、その画面のURLに着目すればよいことになります。なおセキュリティ上の制約で、"_" ではじまるスケルトンおよびサブディレクトリにあるスケルトンは引数では直接呼べません。
なお、スケルトンをカスタマイズする際は、diary.skel のを書き換えるのではなく、diary.user.skel にコピーしてから書き換えるようにしてください。こうすれば diary.skel より優先して読み込まれます。
ですが同時に、バージョンアップをしても常にユーザースケルトンが優先されてしまうので、オリジナルが大幅に書き変わっている場合など多少注意が必要です。後述する特殊スケルトンのうち _main, _main_onelog, _sidebarスケルトンは比較的よく改変されます*1。この3つについては、変更点をバージョンアップアナウンス時にアナウンスしていますのでご注意ください。
あまり使いませんが
diary.user.skel などにおいたユーザースケルトンでは
<$continue()>
という関数(コマンド)を使うことで、本来の diary.skel 内の該当スケルトンに処理を引き継ぐことができます。theme/hatena/_skelton/_frame.htmlなどで使用しています。
特殊な役割をするスケルトン
まず重要なのが外側のフレームを生成するスケルトンです。通常、adiaryの画面は、該当スケルトンを処理し、その結果を埋め込む形でフレームスケルトン(_frame.html)が呼ばれます。サイドバーは、フレームスケルトン内から呼ばれています。
その他特殊なスケルトンは以下の4つです。
_main | 日記本文を生成するスケルントンです。 |
---|---|
_main_onelog | 日記本文生成ですが、記事ID指定時の表示に使われます。 |
_sidebar | サイドバーを生成するスケルトンです。 |
_multiuser_top | マルチユーザーモード時のトップ画面です。 |
このblogレンタルサービスでは、_multiuser_top.html をカスタマイズして diary.user.skel/ に置いてあります。
デザインテンプレート
スケルトンをテーマディレクトリに置くことで「表示画面テンプレート」を作ることができます。例えば、携帯電話用テンプレート(HTMLの元)はtheme/_phone/_skelton/ に置かれています。
デザインテンプレートを作成する際は、theme/ 以下に任意のディレクトリを作成してください。この場合、テンプレート名と同名のテーマ(CSS)が必要になります。中身が空っぽでもいいので必ず置いてください。
theme/my_design/ ならば theme/my_design/_skelton/ に任意のスケルトンを置き theme/my_design/my_design/my_design.css というテーマファイルが必要
(選択中の)テーマディレクトリのスケルトンはユーザースケルトンよりも優先されます(しかしシステムモードではテンプレート(テーマディレクトリスケルトン)は無視されます)。
スケルトンの文法
adiary は Satsuki system という独自のスケルトンシステムにより作成されています。膨大な機能があるシステムですが、文法を簡単に説明しておきます。プログラム経験のある人ならさほど悩まないとは思いますが。
行コメント
<@> コメント
<@> で始まる行はコメントです。現在の仕様では、行の途中に <@> を書いてもコメントとして扱われますが、今後の仕様変更の可能性がある部分ですので、必ず行頭に書いてください。
実行構文
<$xxxx> <@xxxx>
これらは「式」として評価されます。コマンドと言ったりもします。<$~>は実行されますが何も出力されません。<@~>は実行後の結果が出力されます。<@~> は次のような変数置換の形で最もよく使われます。
<li><a href="<@v.this_archive_dir><@v.rss_file>">RSS</a> <li><a href="<@v.myself>?diary_list">過去日記の一覧</a> <li><a href="<@Myself2><@v.path_info>?theme/_print/_print">印刷用の表示</a>
実行構文のコメントアウト
<#$xxxx> <#@xxxx>
このように、コマンド内の先頭に # をつけることで、該当コマンドをコメントアウトできます。コメントアウトしても構文内の ( ) 対応や " "対応はチェックされます。
最適化構文
<@20> 最適化on
コンパイル最適化を指示します。基本的に書き換えないでください。
変数(名前空間)
Satsuki-systemでは、変数の名前空間をピリオドで区切ります。変数名は大文字小文字で区別されます。
<@Myself> <@v.rss_file>
前者は、ルートの中の Myself という変数を、後者は v の中の rss_file というものを示します。
Satsuki-systemでは、小文字で始まる変数名(名前空間)はユーザーに解放されていますが、設計時からの慣習で利用時のメインシステム(この場合adiary)を変数 v の中に入れることになっています。adiary のスケルトンではこのほか、変数 s に各ユーザーの日記帳情報(日記帳の設定情報など)を入れる約束になっています。
このことから、vとs以外の小文字で始まる変数はカスタマイズ時に自由に使うことができます*2。
begin/else/end
これについては、せりかさんの解析記事を参考にしてください。
Satsuki-systemの仕組み
この項目は Perl のオブジェクト指向に理解のある方以外は読まないでください(混乱するだけです)。
Perl では、無名のハッシュリファレンスにライブラリ名(ライブラリ名前空間)を結びつけることでオブジェクト指向を実現しています。Satsuki-system の名前空間というのは、adiary.cgi*3 で生成される Satsuki::Base のオブジェクト $ROBJ の中身そのものです。そしてよく見かける loadpm の実体は new そのものです(ライブラリをロードしてオブジェクトを new して返す)。
Satsuki-system名前空間と実体の対応関係は、次のようになっています。
Satsuki-system | 実体 |
---|---|
<@Myself> | $ROBJ->{Myself} |
<@v.rss_file> | $ROBJ->{v}->{rss_file} |
<@call("sub/sub")> | $ROBJ->call("sub/sub"); |
<$v=loadpm("XXX")> | $ROBJ->{v} = $ROBJ->loadpm("XXX"); |
PerlのTemplateライブラリなどではスケルトンに対しハッシュをバインドできるようですが、Satsuki-system では、システム全体をスケルトンシステムの中に配置しています。Satsuki-system の驚異的な柔軟性と開発効率の要はここにあります。*4
Templateライブラリ | システム ->テンプレート |
---|---|
Satsuki-system | スケルトン ->システム |
実際、adiary.conf.cgi というスタートアップスケルトンを用意しなければ、Satsuki-system はまったく動きませんし、逆にスタートアップスケルトンだけでもある程度のCGIスクリプトを記述するも可能です。
ちなみに adiary.conf.cgi に <$Compile_log_dir="data/log/"> を定義すると、スケルトンが perl スクリプトへコンパイルされる様子をログとして見ることができます(遅くなるので通常はオフにしておきましょう)。