モバゲータウンのノウハウ満載! フレームワークMobaSiFを使おう!

第5回 テンプレートエンジンMTemplate

この記事を読むのに必要な時間:およそ 3 分

前回は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が利用されます。

リスト11 Webアプリケーションロジックからテンプレートを利用する

use MTemplate;
my $html = MTemplate::insert("regist/test", $rhData);
Common::output(¥$html);

第2引数は,変数展開や条件分岐に利用されるハッシュリファレンスです。詳しい利用の仕方については次項「テンプレートファイルの記述方法」とともに説明します。

テンプレートファイルの記述方法

MTemplateのテンプレートファイル独自の記述は「$」「$」の間で行います。あるいは「$で囲まれたタグを利用します」という表現が正しいかもしれません。以下,具体的な記述方法を説明します。

変数展開

リスト12は,テンプレートファイルでの変数展開の記述例です。NAMEはMTemplate::insert( )の第2引数に与えたハッシュリファレンスのキーに対応します。たとえば$rhData->{text}にセットした値によって,$b:=text$が置き換えられます。また,オプションについては表4にまとめました。

リスト12 変数展開の記述例

$=OPTIONS:NAME$

表4 MTemplateで使用するオプション

表記機能詳細
hHTML特殊文字変換下記のような変換を行う。クロスサイトスクリプティングなどへの対策のため,hオプションは常に付けるのが原則
" => "
< => <
> => >
& => &
hn改行コード変換hの処理に加え「\n」「<br />」に変換する
eurl escapeURLに含めてはならない文字をエスケープする(例:半角スペースを%20に変換)
bbypass無変換
条件分岐

条件分岐のときの記述はリスト13のようになります。これらの条件分岐はネスト({ }の間にさらにif文を書くなど)も可能です。

条件文CONDには表5の形式が利用できます。左辺値の変数は,変数展開と同様,ハッシュリファレンスのキーを記述します。右辺値は定数のみ利用できます。また,変数の値が0のとき表5の★印の場合は,Perlの一般的な動作と異なる点にも注意が必要です。

リスト13 条件分岐の記述例

$ if (COND) { $
$ } elsif (COND1 || COND2) { $
$ } elsif (COND1 && COND2) { $
$ } else { $
$ } $

表5 CONDの形式

はたらき
変数=定数文字列比較
変数!=定数文字列比較
変数ne '' ★(空文字との比較なので,変数="0"の場合はTRUE)
!変数eq '' ★(空文字との比較なので,変数="0"の場合はFALSE)
変数>=定数数値比較
変数>定数数値比較
変数<=定数数値比較
変数<定数数値比較
ループ

ループはリスト14の形式になります。ループの中にループを記述することもできます。

リスト14 テンプレートファイル中のループ記述例

$ loop (NAME) { $
$ } $

たとえば,前述の$rhDataについてリスト15のようにハッシュリファレンスを要素に持つリストのリファレンスをセットし,テンプレートファイルにはリスト16のような記述を行うと,出力は図2のようになります。つまり,リストの各要素のハッシュリファレンスに関して変数展開が行われながら繰り返し処理がされるということです。

リスト15 ループに渡すリストの定義例

my @fruits = ( {name => 'apple', price => '100'},
{name => 'orange', price => '120'},
{name => 'melon', price => '500'},
);
$rhData->{List} = \@fruits;

リスト16 リストの各要素を表示するテンプレートファイル例

$ loop (List) { $
$=h:name$ は $=h:price$ 円! 
$ } $

図2 実行結果

apple は 100 円! <br>
orange は 120 円! <br>
melon は 500 円! <br>

著者プロフィール

能登信晴(のとときはる)

大学卒業後,通信キャリアの研究所で国産検索エンジンの研究開発に従事。2004年 1月 株式会社ディー・エヌ・エー入社。「ポケットビッダーズ」「ポケットアフィリエイト」「ペイジェント」などの開発・運用にかかわる。現在は「モバゲータウン」の検索サービス開発を行っている。


川崎修平(かわさきしゅうへい)

学生時代,ネットオークション相場サイト「オークション統計ページ(仮)」を運営。サイトを見たディー・エヌ・エー社員から呼びだされ,2002年1月にアルバイトとして入社。携帯専用オークションサービス「モバオク」を開発後,正社員となり,「ポケットアフィリエイト」「モバゲータウン」などを開発。現在,同社の取締役としてサービスの開発を行っている。

コメント

コメントの記入