最近 handlebars をいじってて、まったく不勉強なためオブジェクトの参照の仕方にはまってたので書きます。
handlebars ってなんですか?
Ember.js が採用していたテンプレートエンジンです。ただ、Ember.js は1.10でHTMLBarsをテンプレートエンジンとして利用するようになったそうなので、今ここでhandlebarsを選択するのが吉なのかはわかりません。Backboneとの相性も良いみたいな記事はよく見てました。
Assemble ってなんですか?
いわゆる静的サイトジェネレーターです。htmlをビルドしてくれるだけなので、middleman server みたいな開発サーバーは起動しません。grunt との親和性が高いので、connect watch assemble をタスクに組込んでlivereloadするのが良さそうではあります。独自のプラグインもそれなりにあります。
ちょっとした100P未満の小規模なサイトの制作向きかなと思います。
自分はmiddlemanに慣れ親しんだけど、assemble & handlebarsもYaml Front Matterでデータをページ単体に持ったりするところや、レイアウト・パーシャルの感覚など、middlemanを通過してればとっつきやすいと感じました。
で、本題。
オブジェクトの参照 - ページの{{each}}
内から
assemble 使っていると(assembleにかかわらずhandlebarsならそうでしょうけど)、ページやパーシャルで{{#each}}
(出た!ひげ!)使ってオブジェクトを参照しますよね。
{{#each pages}}
<li>{{dest}}</li>
{{/each}}
この時の{{dest}}
はpagesの中のkeyです。this.dest
でも取れる。
例えばあるページのフロントマターで
date: "2015-02-14"
title: "valentine's day"
のようなデータを持ってた場合、ページからは{{title}}
のようにデータを参照出来るんですが(もっと言うと構造的には{{page.data.title}}
)、この上の例で言うeachの中ではどう参照すればいいのか。
{{#each pages}}
<li>{{dest}} - {{../title}}</li>
{{/each}}
相対でオブジェクトを参照できるという何かわかりやすいような、ないような感じです。
※ assebmle でページ単位で呼ばれた、page
, pages
オブジェクトが持っているものは{{log page}}
などで確認してみてください。
オブジェクトの参照 - ヘルパーからオブジェクトを参照
module.exports.register = function (Handlebars, options, params) {
'use strict';
Handlebars.registerHelper('foo', function(str) {
return str;
});
};
ヘルパーの解説にありがちなコードです。ページでは{{foo "bar"}}
のように使います。
ただヘルパー作ってると、pages
,page
,また独自で定義したjsonファイルからオブジェクトを作ってsitemap
みたいなオブジェクトを参照したいということがあると思います。
ヘルパーからそのオブジェクトを参照する術を知らなかったので、最初は
Handlebars.registerHelper('buz', function(obj, str1, str2) {
var value = "";
for(i=0;obj.length>i;i++){...}
return val;
});
みたいに、いちいち引数にオブジェクト指定するようなヘルパー書いてた。呼び出す時は、{{buz pages}}
みたいになる。でも、このオブジェクト、絶対にどこでも使うし、毎度引数に入れてるのダサいと思ってたら、ヘルパーの中からもちゃんとオブジェクトを参照出来た。
Handlebars.registerHelper('buz', function(str1, str2) {
var value = "";
for(i=0;this.pages.length>i;i++){...}
return val;
});
でぃ、this で取れるのか…。
ヘルパーで引っかかりそうなところ
オブジェクトの参照とは全く関係ないけど、ヘルパーでhtmlそのまま返す値に突っ込むとエスケープされるので、
return new Handlebars.SafeString(str);
みたいなことする。
本日は以上です。