Handlebarsを使うべきではない言葉なので修正してくださいという同僚がいたので、まとめてみます。
ただのテンプレートエンジンでデータバインディングとかはないんですが、もし使いどころがあればご参考までに。
基本的には、
http://handlebarsjs.com/
に詳しく書いてあるので、そちらを見てください。
Handlebarsとは
Handlebarsとはいわゆるテンプレートエンジンで、
JavaScriptの値を参照してHTMLを生成できるもの。
書き方
テンプレートは
<div>{{name}}</div>
<div>{{age}}</div>
という書き方をします。
{{XXX}}内のxxxはJavaScriptのプロパティです。
{{XXX}}と書くことにより、JavaScriptの値を参照して、
それをHTMLとして生成します。
<div>{{person.name}}</div>
<div>{{person.age}}</div>
という書き方もできます。そのときは値を
person : {
name: "Satoshi",
age : 33,
}
}
みたいに渡してあげることが可能です。
Handlebarsを試す
まずはjQueryとhandlebarsをインストールします。
$ bower install jquery handlebars
ではちょっと試しに書いてみましょう。
<html>
<head>
<script type="text/javascript" src="./bower_components/jquery/dist/jquery.min.js"></script>
<script type="text/javascript" src="./bower_components/handlebars/handlebars.min.js"></script>
<script type="text/x-handlebars-template" id="template">
<h1>{{name}}</h1>
<div>{{age}}</div>
</script>
<script>
window.onload = function() {
var source = $("#template").html();
var template = Handlebars.compile(source);
var values = {
name : "Satoshi Watanabe",
age : 33
};
var html = template(values);
console.log(html);
$("#contents").html(html);
}
</script>
</head>
<body id="contents">
</body>
</html>
これを行うことにより
<h3>Satoshi Watanabe</h3>
<div>33</div>
が表示できます。
build-inのhelper
Handlebarsにはいくつかhelperが用意されているので、それを紹介します。
each
eachはイテレータとして、要素を順番に使用できます。
<table border="1">
{{#each momoclo}}
<tr>
<td>{{name}}</td>
<td>{{color}}</td>
</tr>
{{/each}}
<table>
とした場合、momocloオブジェクトの要素をひとつひとつ参照します。
var source = $("#template").html();
var template = Handlebars.compile(source);
var values = {
momoclo : [
{name : "Kanako Momota", color: "red"},
{name : "Ayaka Sasaki", color: "pink"},
{name : "Shiori Tamai", color: "yellow"},
{name : "Momoka Ariyasu", color: "green"},
{name : "Reni Takagi", color:"purple"},
]
};
var html = template(values);
$("#contents").html(html);
if / unless
{{#if author}}
<h1>{{firstName}} {{lastName}}</h1>
{{else}}
<h1>Unknown Author</h1>
{{/if}}
authorがtrueになれば、firstName, lastNameを出力します。
なければ、else以下を実行します。
unlessはifの逆でauthorがfalseになれば、実行します。
{{#unless author}}
<h1>Unknown Author</h1>
{{else}}
<h1>{{firstName}} {{lastName}}</h1>
{{/unless}}
with
withはJavaScriptのwithと同じです。
テンプレートを
{{#with momoclo}}
<div>{{Kanako}}</div>
<div>{{Ayaka}}</div>
<div>{{Shiori}}</div>
<div>{{Momoka}}</div>
<div>{{Reni}}</div>
{{/with}}
JavaScriptを
var values = {
momoclo : {
Kanako : "red",
Ayaka : "pink",
Shiori : "yellow",
Momoka : "green",
Reni : "purple",
}
};
var html = template(values);
とかくと、出力は以下のようになります。
<body id="contents">
<div>red</div>
<div>pink</div>
<div>yellow</div>
<div>green</div>
<div>purple</div>
</body>
lookup
lookupはあるデータをとりだしてそれを別なデータを取り出すのに使うのに使ったりします。
たとえば、
var values = {
momoclo : [
{firstname : "Kanako", lastname : "Momota"},
{firstname : "Ayaka", lastname : "Sasaki"},
{firstname : "Shiori", lastname : "Tamai"},
{firstname : "Momoka", lastname : "Ariyasu"},
{firstname : "Reni", lastname : "Takagi"},
],
color : {
"Kanako" : "red",
"Ayaka" : "pink",
"Shiori" : "yellow",
"Momoka" : "green",
"Reni" : "purple",
}
};
というデータがあったとして、
momocloのfirstnameからcolorの値が取りたいとき、以下のようにします。
<ul>
{{#each momoclo}}
<li>{{lookup ../color firstname}}</li>
{{/each}}
</ul>
そうすると、以下のような出力が得られます。
<ul>
<li>red</li>
<li>pink</li>
<li>yellow</li>
<li>green</li>
<li>purple</li>
</ul>
その他(時間があったときに追記)
- log
- blockHelperMissing
- helperMissing
自分でhelperを定義する
helperはHandlebars.registerHelper()を使って自分で定義できます。
例えば、linkを生成する
Handlebars.registerHelper('link', function(text, url) {
return new Handlebars.SafeString(
"<a href='" + url + "'>" + text + "</a>"
);
});
というものを用意してあげると、
データを
var values = {
momoclo : [
{name : "Kanako Momota", url: "http://ameblo.jp/momota-sd/"},
{name : "Ayaka Sasaki", url: "http://ameblo.jp/sasaki-sd/"},
{name : "Shiori Tamai", url: "http://ameblo.jp/tamai-sd/"},
{name : "Momoka Ariyasu", url: "http://ameblo.jp/ariyasu-sd/"},
{name : "Reni Takagi", url:"http://ameblo.jp/takagi-sd/"},
]
};
としたときは、以下のように書くことができます。
<ul>
{{#each momoclo}}
<li>{{link name url}}</li>
{{/each}}
</ul>
そうすると結果は以下のようになります。
<ul>
<li><a href="http://ameblo.jp/momota-sd/">Kanako Momota</a></li>
<li><a href="http://ameblo.jp/sasaki-sd/">Ayaka Sasaki</a></li>
<li><a href="http://ameblo.jp/tamai-sd/">Shiori Tamai</a></li>
<li><a href="http://ameblo.jp/ariyasu-sd/">Momoka Ariyasu</a></li>
<li><a href="http://ameblo.jp/takagi-sd/">Reni Takagi</a></li>
</ul>
プリコンパイル
Handlebarsにはプリコンパイルしておくことが可能です。
ページの読み込むときにコンパイルする必要がないので、こちらをやっておくてページの表示が早くなります。
handlebarsのnpmでインストールしておき、使います。
$ npm install handlebars
テンプレートファイルを用意します。
<div>{{person.name}}</div>
<div>{{person.age}}</div>
<div>{{person.sex}}</div>
テンプレートファイルをプリコンパイルします。
$ handlebars test-template.hbs -f test-template.js
それをhtmlに記述します。
使うJavaScriptはhandlebars.jsでもhandlebars.runtime.jsでもどちらでも大丈夫です。
<div id="output">
<script type="text/javascript" src="./bower_components/jquery/dist/jquery.min.js"></script>
<script type="text/javascript" src="./bower_components/handlebars/handlebars.runtime.min.js"></script>
<script type="text/javascript" src="./test-template.js"></script>
<script type="text/javascript">
var html = Handlebars.templates['test-template.hbs']({
person : {
name: "Satoshi",
age : 33,
sex : 'M'
}
});
$('#output').html(html);
</script>
これにより、以下が出力されます。
<div id="output">
<div>Satoshi</div>
<div>33</div>
<div>M</div>
</div>
ここはGruntで自動化できそうですね。
grunt-contrib-handlebarsを使いましょう。
API
Handlbars.xxx のようなメソッドはいくつかあるので、
http://handlebarsjs.com/reference.html
を参照してください。