“Template” – Alphabetical Advent Calendar 2013
この記事は賞味期限切れです。(更新から1年が経過しています)
“T” は Template の “T”。
テンプレート
動的なWebアプリケーションを制作する上で、 テンプレートは非常に強力な味方になります。 それだけにテンプレートエンジンはまさに群雄割拠で、 それぞれ個性や独自の趣向をもったライブラリが至る所で開発されています。
基本的な機能
どのテンプレートエンジンも記法こそ様々ですが、提供する機能や使い方は基本的に共通しています。 出力用の関数が用意されており、その関数に元となるテンプレート文字列と、 その中で展開したいデータを格納したオブジェクトを渡します。
例えば Mustache では render メソッドがそれにあたります。
var output = Mustache.render(template, data);
render の中では、テンプレートの記述を元にして data オブジェクトの内容を展開していきます。 例えばこのようなテンプレートが文字列で用意されているとして、
<a href="mailto:{{email}}">{{name}}</a>
これを次のような data オブジェクトで展開したいとします。
var data = {
name: "John",
email: "john@example.com"
};
これらを Mustache.render メソッドに渡すと、次のような出力が文字列で返されます。
<a href="mailto:john@example.com">John</a>
制御構文
テンプレートエンジンは、データのコレクションをループで回して全部出力させたり、 条件分岐を行なって true の場合のみ出力させたりといった機能を提供してくれます。
<ul>
<!-- products(配列)の中のオブジェクトを全て出力 -->
{{#products}}
<li>{{name}} : {{price}}</li>
{{/products}}
</ul>
<!-- isError が true の場合だけ出力 -->
{{#isError}}
<strong>エラーです</strong>
{{/isError}}
これは Mustache での制御構文の例です。(制御構文の書き方はライブラリによって大きく異なります)
テンプレートのコンパイル
Mustache.render のようにテンプレートとデータを渡して出力する方法の他に、 テンプレートをコンパイルしてしまって繰り返し再利用可能な関数にしてしまう事もできます。 コンパイルも多くのテンプレートエンジンで実装されています。
var render = Mustache.compile(template);
var output = render(data);
何度も繰り返し使うようなパーツはコンパイルしてしまったほうが、 人にもパフォーマンスにも優しそうです。
テンプレート文字列
Web開発においてテンプレート文字列の内容は主に HTML であり、JavaScript の文字列リテラルで表現するには長過ぎます。 そこで、次のように script 要素の中に閉じ込めてしまう手法がよくとられます。
<script type="text/template" id="template-profile">
<div class="profile">
<div class="name">{{name}}</div>
<div class="email">{{email}}</div>
</div>
</script>
<script>
var template = document.getElementById("template-profile").innerHTML;
</script>
テンプレートエンジンライブラリの色々
どのライブラリも記法・機能が千差万別です。 自分のスタイルや、プロジェクトに合ったテンプレートエンジンを選択しましょう。
Mustache
Mustache の特徴として、「多言語に対応している」事と、「ロジックレスである」事が挙げられます。 JavaScript の他にも20言語(2013年12月現在)にわたって実装されていて、 サーバサイドでもフロントでも同じ記法でテンプレートを書くことができます。
<section>
<h1>{{title}}</h1>
{{#onsale}}<strong>セール中!</strong>{{/onsale}}
<ul>
{{#items}}
<li>{{name}} : {{price}}</li>
{{/items}}
</ul>
</section>
ループや条件分岐は {{#name}} で表現する為、複雑な制御は出来ません。
hogan.js
http://twitter.github.io/hogan.js/
hogan.js は Mustache 互換のテンプレート記法を採用した、Twitter が提供するテンプレートエンジンです。 Mustache と変わらない記述で、本家よりも速く動作するとしています。 出力の仕方は Mustache と変わりありません。
var output = hogan.render(template, data); // 出力
var render = hogan.compile(template); // コンパイル
EJS
https://github.com/visionmedia/ejs
Ruby の ERB スタイルでテンプレートを書ける JavaScript のライブラリです。 Mustache系と違って、テンプレート内にそのまま JavaScript コードを記述する事ができます。
<section>
<h1><%= title %></h1>
<% if(onsale) { %>
<strong>セール中!</strong>
<% } %>
<ul>
<% items.forEach(function(item){ %>
<li><%= item.name %> : <%= item.price %></li>
<% }) %>
</ul>
</section>
テンプレートにロジックが必要な場合は非常に強力な味方になりますね。 記述もタグで囲むだけのシンプルなもので、 Ruby 開発者は勿論、PHP の開発者にとっても馴染みのある書き方なのではないでしょうか。
出力に使うメソッド名は上に上げたものと変わりません。
var output = ejs.render(template, data); // 出力
var render = ejs.compile(template); // コンパイル
underscore
underscore.js は便利なメソッドを多数提供してくれる大変有難いライブラリですが、 その中の _.template メソッドがテンプレートエンジンとして働いてくれます。
テンプレートの記述は ERB に倣った物で、上の EJS で書いたテンプレートがそのまま _.template で動作します。 出力もコンパイルも同じメソッドで行います。
var output = _.template(template, data); // 出力
var render = _.template(template); // コンパイル
一番の魅力は、この機能が underscore.js の一部でしかないという点だと思います。 他の便利なメソッドを使う為に、あるいは Backbone.js を使う為にインクルードしておいた underscore.js がテンプレートエンジンとしても働き、 新たに別のライブラリを読み込む必要がないのです。
コメント