前回はMobaSiFに含まれる個々のPerlモジュールを解説しました。今回は、MobaSiFに含まれるテンプレートエンジンMTemplateについて説明します。
テンプレートエンジンMTemplate
MobaSiFに付属するテンプレートエンジンMTemplateは、次のような特徴を持ちます。
- 1つのテンプレートファイルで3キャリアに対応
1つのテンプレートファイルを記述するだけで、3キャリアに対応できます。また、キャリアごとに表示する内容を変えることもできます。
- 事前コンパイルにてバイナリテンプレート生成
HTTPリクエストを受け付けるたびにテンプレートをparseするのは非効率と考え、事前コンパイルによりバイナリテンプレートを生成する方式をとっています。
- mmapによる共有メモリの利用
DeNAのサービスで長く使われているFastCGIでは、プロセス上のメモリキャッシュを利用するとアプリケーションプロセスごとにメモリが利用されてしまい非効率です。そこで、UNIX系のシステムコールであるmmap( )を使い、ファイルをメモリにマップして各アプリケーションプロセスから共通のメモリ領域を利用できるようにしています。
- XSによる高速処理
主要部分がC言語で実装されているため処理が高速です。
MTemplateの利用の流れ
(1)テンプレートファイルの作成
テンプレートファイルはtemplate/_system以下に.htmlという拡張子を付けて置きます。文字コードはShift-JISを利用します。テンプレートファイルで利用できる独自タグなどについては後述します。
(2)テンプレートファイルのコンパイル
script/tool/compile_templateコマンドを実行すると、templateディレクトリ以下のテンプレートファイルのうち、前回のコンパイル以後に変更のあったファイルがすべてコンパイルされます。コンパイル結果はdata/html_binディレクトリに出力されます。
Webサーバ(Webアプリケーション)が起動している場合でもコンパイルされたテンプレートは即時に反映されるので、再起動は不要です。
(3)Webアプリケーションロジック(.pmファイル)から呼び出す
リスト11は、Webアプリケーションロジックからテンプレートを利用する例です。MTemplate::
insert( )の第1引数はテンプレートファイル名で、template/_systemからの相対パスで記述し、拡張子.htmlは省略します。たとえば上記の利用例では、template/_system/regist/test.htmlが利用されます。
第2引数は、変数展開や条件分岐に利用されるハッシュリファレンスです。詳しい利用の仕方については次項「テンプレートファイルの記述方法」とともに説明します。
テンプレートファイルの記述方法
MTemplateのテンプレートファイル独自の記述は「$」と「$」の間で行います。あるいは「$で囲まれたタグを利用します」という表現が正しいかもしれません。以下、具体的な記述方法を説明します。
変数展開
リスト12は、テンプレートファイルでの変数展開の記述例です。NAMEはMTemplate::insert( )の第2引数に与えたハッシュリファレンスのキーに対応します。たとえば$rhData->{text}にセットした値によって、$b:=text$が置き換えられます。また、オプションについては表4にまとめました。
表4 MTemplateで使用するオプション
表記 | 機能 | 詳細 |
h | HTML特殊文字変換 | 下記のような変換を行う。クロスサイトスクリプティングなどへの対策のため、hオプションは常に付けるのが原則
" => "
< => <
> => >
& => & |
hn | 改行コード変換 | hの処理に加え「\n」を「<br />」に変換する |
e | url escape | URLに含めてはならない文字をエスケープする(例:半角スペースを%20に変換) |
b | bypass | 無変換 |
条件分岐
条件分岐のときの記述はリスト13のようになります。これらの条件分岐はネスト({ }の間にさらにif文を書くなど)も可能です。
条件文CONDには表5の形式が利用できます。左辺値の変数は、変数展開と同様、ハッシュリファレンスのキーを記述します。右辺値は定数のみ利用できます。また、変数の値が0のとき(表5の★印)の場合は、Perlの一般的な動作と異なる点にも注意が必要です。
表5 CONDの形式
式 | はたらき |
変数=定数 | 文字列比較 |
変数!=定数 | 文字列比較 |
変数 | ne '' ★(空文字との比較なので、変数="0"の場合はTRUE) |
!変数 | eq '' ★(空文字との比較なので、変数="0"の場合はFALSE) |
変数>=定数 | 数値比較 |
変数>定数 | 数値比較 |
変数<=定数 | 数値比較 |
変数<定数 | 数値比較 |
ループ
ループはリスト14の形式になります。ループの中にループを記述することもできます。
たとえば、前述の$rhDataについてリスト15のようにハッシュリファレンスを要素に持つリストのリファレンスをセットし、テンプレートファイルにはリスト16のような記述を行うと、出力は図2のようになります。つまり、リストの各要素のハッシュリファレンスに関して変数展開が行われながら繰り返し処理がされるということです。
共通要素の読み込み
先述した変数展開や制御構造以外に、テンプレートで共通的に利用される要素を読み込む機能があります(リスト17)。上から順に利用例を解説します。
- $INC:NAME$…template/_inc_html.txtの内容をインクルード
テンプレートファイルに$INC:header$と記述すると、template/_inc_html.txtファイルの$INCDEF:header$と$/INCDEF$で囲まれた部分が挿入されます。
- $CON:NAME$…template/_const.txtの定数定義を使用
template/_const.txtファイルに「title : MobaSiF」と書かれている場合、テンプレートファイルに$CON: title$と記述すると、MobaSiFに置換されます。
- $STY:NAME$…template/_style.txtのスタイル定義を使用
template/_style.txtファイルにリスト18のような記載があるとします。
その場合、
は
となります。
キャリア単位の出し分け
接続元のキャリアによる表示の出し分けは、リスト19のタグを利用します。DOMAINSは小文字のd(NTTドコモ)、a(au)、v(ソフトバンクモバイル)で指定し、複数ある場合はカンマ(,)で区切ります(リスト20)。
その他の機能
- $ENC:STRING$
文字列STRINGをURLエスケープします。URL中に日本語を入れる場合などに便利です(リスト21)。
- ::TIME(YYYY/[M]M/[D]D [H]H:II)
unixtimestampの数値に変換され、主にif分の定数部分に利用されます(リスト22)。
サンプルアプリケーションの紹介
MobaSiFには、別途サンプルアプリケーションが用意されており(本稿執筆時のファイル名はmoba-0.9.0-sample-1.0.tar.gz)、会員登録機能や日記の入力・一覧・コメント機能などが含まれています。インストール・設定後はトップページ(サーバのドメイン名がexample.comであればhttp://example.com/)からたどることで動作を確認できるようになっており、またconf/pages.confファイルにページの登録があります。このサンプルアプリケーションを参考にすると、MobaSiFからDBを利用する方法も理解していただけると思います。ぜひ参考にしてください。
おわりに
本特集では、MobaSiFのメリットと利用方法を説明してきました。MobaSiFを利用するとケータイ向けサイトを簡単に開発できると思いますので、ぜひ利用してみてください。また、モバゲータウンのような大規模ケータイサイトのフレームワークがどのようになっているか覗いてみるという楽しみもあると思います。
MobaSiFにはここで取り上げた以外の機能もありますが、本稿では主にケータイ向けWebアプリケーションに特化した機能に焦点をあてて解説しました。ほかの機能に関する情報や、最新の情報などはMobaSiFのdocsフォルダ内ドキュメントにも含まれており、また本稿の訂正情報も含め下記サイトでもお伝えしていく予定です。
- SourceForge.jp上のプロジェクトページ
- URL:http://sourceforge.jp/projects/moba/
- DeNA技師のメモ
- URL:http://d.hatena.ne.jp/tokiharu/