LoginSignup
350
325

JavaScriptのテンプレートエンジンHandlebars入門

Last updated at Posted at 2014-09-06

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

ではちょっと試しに書いてみましょう。

test.html
<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

テンプレートファイルを用意します。

test-template.hbs
<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でもどちらでも大丈夫です。

test.html
<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
を参照してください。

350
325
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
350
325