Hogan.jsを使ってみた
以前にも「google-jstemplateを使ってみる」でJavaScriptのテンプレートエンジンを使ってみたを書いたが、個人的にはいまいちだったのでTwitter製ということでHogan.jsを使ってみた。
売りとしてはTwitter製の2.5kのテンプレートエンジンで、事前にコンパイルしておくこともできるし、ブラウザに読み込んで動的な処理も出来る。node.jsを使って開発しているのであればnpmからインストール可能。
npm install hogan.js
仕様としてはmustacheのテストスイートを通るように作成されているのでここに記載されている事ができる。mustacheとしてはロジックレステンプレートとして謳っていて、最初は「ロジックレスなテンプレート?ループや出し分けとか出来ないということなのか?」と思っていたが、そうではなくifやelseやループが無いかららしい。代わりにタグが有るとのこと。簡易的なjspのtaglibっぽいイメージのようだ。
使い方としては今回はnode.jsは使わなかったのでブラウザに直接読み込んで利用。そして以下がテンプレートの例。タグには「{{」、「}}」を使う。
<!DOCTYPE html> <html> <head> <script src="http://www.google.com/jsapi"></script> <script>google.load('jquery', 1);</script> <script src="http://twitter.github.com/hogan.js/builds/2.0.0/hogan-2.0.0.js"></script> <script type="text/template" id="tmpl"><span>{{name}}</span></script> <script> $(function() { var tmpl = Hogan.compile($('#tmpl').text()); $('#test').append(tmpl.render({name: 'wata'})); }); </script> </head> <body> <div id="test"></div> </body> </html>
上記は簡単にテンプレートに変数の値を展開して<div id="test"></div>に入れている。デフォルトでhtmlエスケープされているので、そのまま出したい場合は「{{{」、「}}}」で囲む。
<!DOCTYPE html> <html> <head> <script src="http://www.google.com/jsapi"></script> <script>google.load('jquery', 1);</script> <script src="http://twitter.github.com/hogan.js/builds/2.0.0/hogan-2.0.0.js"></script> <script type="text/template" id="tmpl"> <span>{{name}}</span><br> {{script}}<br> {{{script}}} </script> <script> $(function() { var tmpl = Hogan.compile($('#tmpl').text()); $('#test').append(tmpl.render({ name: 'wata' , script: '<span style="color: red">red font</span>' })); }); </script> </head> <body> <div id="test"></div> </body> </html>
タグなので開始と修了でくくったセクションという概念も存在する。囲み方としては「{{#person}}~{{/person}}」という感じだ。中の値によって挙動が変わるので、単純な値の場合でfalsyな値の場合は単純なifとして動作し、囲まれている中身はまるごと表示されない。truthyな値の場合は単純なifとして評価され(評価を反転させたい場合は頭に「^」をつける。{{^person}}~{{/person}})、そして値が空のリストで無い場合はループとして評価される。以下はルートして評価した場合の例。
<script type="text/template" id="tmpl">
<ul> {{#person}} <li>{{name}}</li> {{/person}} </ul>
</script>
<script>
$(function() {
var tmpl = Hogan.compile($('#tmpl').text());
$('#test').append(tmpl.render({
person: [{name: 'wata'}, {name: 'puyo'}, {name: 'hogan'}]
}));
});
</script>
使い道がよくわかっていないがLambdasというのもある。値が呼び出し可能なオブジェクトの場合(つまり関数の場合)は中身のテキストを引数に渡し、戻り値を表示するという物。公式ドキュメントにはフィルターやキャッシュ機構を作るためと書いてあるが、渡されるテキストはテンプレートの展開前なので「<li>{{name}}</li>」とかが来る。Lambdasでは自前でそれを展開しないと行けない。何回も同じ値が出てきて、その回数によってフォントを大きくしたいとかそういう場合に使うものなのだろうか・・・。
一応テンプレート上で評価されないコメントの書き方もあり感嘆符を頭につける。
{{! comment}}
次はPartials。別のテンプレートの呼び出し機能。例えば上にも下にも同じようなテンプレートになった場合はPartialとして別定義し、関数呼び出し様に使えるということ。使い方としてはtmpl.renderの第2引数にPartialsを渡すようにする。
<script type="text/template" id="p-tmpl"> <strong>{{nickname}}</strong> </script> <script type="text/template" id="tmpl"> <ul> {{#person}} <li>{{name}}{{#nickname}} {{> nick}}{{/nickname}}</li> {{/person}} </ul> </script> <script> $(function() { var tmpl = Hogan.compile($('#tmpl').text()); var partial = Hogan.compile($('#p-tmpl').text()); $('#test').append(tmpl.render({ person: [ {name: 'wata', nickname: 'わた'} , {name: 'puyo'} , {name: 'hogan', nickname: 'ほーがん'} ] }, { nick: Hogan.compile($('#p-tmpl').text()) })); }); </script>
mustacheとしては単なる仕様で言語に捕らわれないので、サーバサイドと共有することも可能といえば可能。それよりはmustacheの構文を覚えるのが簡単だったというのがメリットな気もする。jquery-templateやgoogle-jstemplateよりはおすすめのテンプレートエンジンだ。