TTerse Template Toolkit互換の構文
KolonはXslateの機能を引き出すのに最適な構文です。しかしXslateでは、TT2からの移行を容易にするために、TT2のサブセットであるTTerseという構文も用意しています。
TTerseの使い方
TTerseを使うには、Text::Xslate->new()メソッドのsyntaxオプションに「TTerse」を渡します。別のディストリビューションとして配布しているText::Xslate::Bridge::TT2Likeを使うと、TT2組み込みのメソッドやフィルタを使えるようにもなります(リスト17)。
TT2とTTerseの違い
TTerseは既存のTT2テンプレートを置き換えることを目的としており、高い互換性を持っています。しかし、TT2の仕様は非常に大きく複雑なため、すべての機能を実装しているわけではありません。テンプレートの外部環境へアクセスするUSEディレクティブや、任意のPerlコードを実行するための構文など、機能の制約というコンセプトから逸脱しているために意図的に取り除いている機能もあります。リスト7のようにテンプレート式を自動エスケープする点もTT2とは異なります。ただしこれに関しては、二重エスケープを防止するメカニズムによって、htmlフィルタの適用結果はTT2とほぼ等しくなります。
また、TT2は記号の意味がコンテキストによって異なることがありますが、TTerseではそのようなケースをなくし、可能な限り意味が一意になるようにしています。そのような非互換な例としては、リスト18のようなものがあります。
TTerseを使うことの利点は、TT2に親しんだエンジニア/デザイナであれば、わずかな違いを覚えるだけで済むことです。その一方で、Xslateの大きな特徴の一つであるカスケードは利用できません。
Text::Clevery Smarty互換の構文
Text::CleveryはPHPのSmartyというテンプレートエンジンと互換性のある構文です。大規模な拡張なので別のディストリビューションにしていますが、CPANにアップロードしてあるので、Text::Xslate同様にCPANクライアントでインストールできます。Cleveryは既存のSmartyアプリケーションをPerlに移植することを想定しています。ただしSmartyの微妙な挙動を再現するために、実行速度はKolonやTTerseより若干遅くなる傾向があります。
Cleveryを使用するときは、リスト19のようにrender()にPSGI リクエストを渡すことで、$smarty.getや$smarty.postが使用できるようになります。
CleveryもやはりSmartyと異なる点がいくつかあるものの、Smartyに親しんだエンジニア/デザイナであればすぐに使いこなせるでしょう。しかしSmartyに慣れているのでなければ、あえてCleveryを選択する理由はありません。
Xslateの拡張
組み込み関数やメソッドについては、Xslateのコアは必要最小限に絞っています。しかし拡張性は確保しているため、関数やメソッドを追加することは簡単です。Xslateの拡張はperldoc Text::Xslate::Manual::Cookbookでもいくつか紹介しているため、そちらも参考にしてください。
モジュールを使う
カレントディレクトリを得るCwd.pmやJSONデータの操作に使うJSON.pmのような関数インタフェースを備えたモジュールは、リスト20のようにmoduleオプションで利用できます。
関数を追加する
クラスメソッドを使うインタフェースを備えたモジュールを使うには、ラッパー関数を作ってfunctionオプションに渡します。また、HTMLソースコードを組み立てて返すモジュールについては、戻り値を自動エスケープ回避するための印を付ける必要があるため、ラッパー関数が必要です。ラッパー関数はhtml_builder()というユーティリティ関数で簡単に作成できます。
リスト21はfunctionオプションを使用する一例です。
メソッドを追加する
オブジェクトについては、あらゆるメソッドを呼び出すことができるため、Xslate側で拡張する必要はありません。配列やハッシュなどの基本型については、ブリッジモジュールを作成することで拡張できます。詳細はperldoc Text::Xslate::Bridge
を参照してください。なお、作成したブリッジモジュールをText::Xslate::名前空間に置く必要はありません。
落穂拾い
最後に、紙幅の都合で詳しく掘り下げられなかった点について少しだけ触れておきます。
UTF-8の扱い
Xslateの文字列の扱いは、モダンなテキスト処理モジュールに準じています。すなわち、操作の対象はPerlの文字列であり、Perl APIを使って連結や比較をしています。したがって、Perlの文字列を渡せば、Perlレベルと同じように動くことが期待できます。テンプレート変数についてはデコードして渡してください。またrender()メソッドの戻り値を出力する際にはエンコードする必要があります。
テンプレートファイルのエンコーディングはデフォルトではUTF-8とみなしますが、これは変更可能です。
xlsateコマンド
Xslateをインストールすると、xslateというコマンドもインストールされます。これは、あるディレクトリ以下のテンプレートファイルを一括で処理するものです。また、perlコマンドのように、-eスイッチでワンライナーを実行することもできます。
詳細はperldoc xslate
を参照してください。
マクロ
Xslateはマクロもサポートしています。マクロはKolonとTTerseで利用でき、テンプレートを構造化したり、関数やメソッドのコールバックとして渡したりすることができます。
詳細はperldoc Text::Xslate::Syntax::Kolon
およびperldoc Text::Xslate::Syntax::TTerse
を参照してください。
Data::Section::Simpleとの連携
Text::Xslate->new()メソッドのpathオプションにハッシュリファレンスを渡せることはすでに述べました。この機能と__DATA__
以下のデータを構造化するData::Section::Simpleを組み合わせると、スクリプトとテンプレートを1つのファイルにまとめることができます。
具体例はperldoc Text::Xslate::Manual::Cookbook
にあります。
デバッグ
テンプレートのデバッグにはdumpフィルタが使えます。これは、Data::Dumperを使って変数の内容を整形するフィルタです。このほか、デバッグについての詳細はperldoc Text::Xslate::Manual::Debugging
にまとめてあります。
おわりに
本記事では、テンプレートエンジンXslateを紹介しました。従来のテンプレートエンジンと比較して高速かつ安全であり、PSGIアプリケーションとの相性も抜群です。また、TT2やSmartyからの移行を簡単に行うためのサポートもあります。これを機にお試しくださると幸いです。
次回の執筆者は奥一穂さんで、テーマはシステムプログラミングです。筆者もシステム寄りの技術で奥さんにご意見をいただくことがあるため、個人的にも非常に楽しみです。