Handlebarsがいいかもという話

Pocket
[`evernote` not found]

このブログでも何度か登場していますが、jqueryのテンプレートエンジンであるhandlebars.jsがとても扱いやすいと思いますので、備忘録も兼ねて、使い方をまとめてみたいと思います。

Handlebars.jsとは?

handlebars.jsは、jqueryのテンプレートエンジンです。jsonやxmlを展開してhtmlを生成する時にテンプレートとして利用できます。
jqueryでは.append()のようなコンテンツを追加するプロパティが用意されています。ただこれだけだと、複雑な構造を吐き出すときは、どうてもメンテナンス性が悪くなってしまいますので、handlebar.jsのようなテンプレートエンジンを利用したほうが、コードがすっきりします。

なんでそんなものを使うの?

一番は、メンテナンス性だと思います。
例えば、

<div class="entry">
  <h2>タイトルだよ</h2>
  <p>本文だよ</p>
</div>

こんな形で動的にコードを展開しなければならない場合、
jqueryの.append()で書くと

append('<div class="entry"><h2>'+ title + '</h2><p>' + content+ '</p></div>')

※title とか contentが変数として動的に入る部分です。

こんな風に書かなければなりません。
この程度ならなんとかなりますが、もっと複雑なコードの場合、メンテナンスどころではなくなってしまいます。

Handlebars.jsだとどうなるの?

まずjqueryとhandlbars.jsを読み込みます。
次に、htmlとして展開するテンプレートを定義します。

先述のような形に吐き出したい場合は

<script id="template" type="text/x-handlebars-template">
{{#each this}}
<div class="entry">
  <h2>{{title}}</h2>
  <p>{{content}}</p>
</div>
{{/each}}
</script>

この様に定義します。
先ほどのコードよりもかなり見通しが良くなったと思います。
Handlebars.jsの場合、動的に入る部分は{{title}}、{{content}}のように表現します。

あとは、jsonなりxmlを読み込んで、予め定義してある{{title}}とか{{content}}に要素を放り込んで、このテンプレートで生成したhtmlを吐き出したい場所に.append()してあげればよい訳です。

$.ajax({
  url: '[path]',
  dataType: 'json',
  success: function(data){
          var posts = data.posts;
          //jsonを展開して、feedsItemという配列に必要な要素を放り込む
          for (var i = 0; i < posts.length; i++) {
                    var post = posts&#91;i&#93;;
                    var feedsItem = &#91;{
                    title:post.title,
                    content:post.content
          }&#93;;
          //事前に定義したテンプレートを呼び出だす
          var template = Handlebars.compile($('#template').text());
          //呼び出されたテンプレートに展開された情報を流し込んで、表示される
          $('#feed').append( template(feedsItem) );
          }
     }
});
&#91;/javascript&#93;

jsonを展開する部分は、読み込むjsonによって変数を変えなければならないので、そのままコピペでは動かない場合があります。

<h4 class="subTitle"><span>ちょっと高度な使い方 htmlをエスケープしない</span></h4>
個人的にこのテンプレートエンジンを使ってよくやるのが、ブログなどのrss情報を引っ張ってきて、コンテンツを生成することですが、jsonの中にhtmlタグがある場合、エスケープされて、タグも文字列として表示されてしまいます。

こんな時はテンプレート側で{{{content}}}
のように、かっこを3つにしてあげると、htmlタグがエスケープしないで、タグとして表示してくれます。
便利です。

[javascript]
<script id="template" type="text/x-handlebars-template">
{{#each this}}
<div class="entry">
  <h2>{{title}}</h2>
  <p>{{{content}}}</p>
</div>
{{/each}}
</script>

ブログのRSSを引っ張ってきて表示する程度であれば、このくらいの知識で十分です。
(jsonpで吐き出されていない場合はクロスドメインの対策が必要になりますが)

DEMO

また、ヘルパー関数という、テンプレートエンジン側で表示を制御する関数(ifとかeach)も用意されていますので、そういった機能を利用するとスマホサイトとか、アプリといった複雑な案件でも利用が出きるんじゃないかと思います。今までサーバー側でしかできなかったような表現が、java scriptだけで実現できるようになりますので、覚えておくといいかもしれませんね。

Follow me!

Pocket
[`evernote` not found]

コメントは受け付けていません。