今回は、
前回お伝えした通り、
式の実行
前回もお伝えしていますが、{{式}}
という構文で式を実行し、
{{personName}}さん、こんにちは!
また、
{{person.name}}さん、こんにちは!
また、
{{#with family}}
{{#with mother}}
お母さんの名前は{{name}}です。
<!-- ../により、family変数を参照できる -->
お父さんの名前は{{../father.name}}です。
{{/with}}
{{/with}}
上のテンプレートに対応するJavaScriptコードは以下になります。
if (Meteor.isClient) {
// 式personNameに対応する値
Template.simpleVar.personName = 'こうたろう';
// 式personに対応する値
Template.nestedVar.person = {
name: 'ちほ'
};
// 式familyに対応する値
Template.parentVar.family = {
father: { name: 'しゅんぺい' },
mother: { name: 'たえこ' }
};
}
実行結果は以下のようになります。

サンプルは以下からダウンロードできます。
ブロック構造の使用
Handlebarsには、
#withブロック
#withブロックは、date
は日時の情報を格納したオブジェクトです。
現在時刻は
{{currentDate.year}}年
{{currentDate.month}}月
{{currentDate.date}}日
{{currentDate.hours}}時
{{currentDate.minutes}}分
{{currentDate.seconds}}秒
です。
#withブロックを使用すると、
現在時刻は
{{#with currentDate}}
{{year}}年
{{month}}月
{{date}}日
{{hours}}時
{{minutes}}分
{{seconds}}秒
{{/with}}
です。
#withブロックのサンプルは以下からダウンロードできます。
#ifブロック
条件分岐を行うためのブロックです。引数の真偽値に応じて、
以下のテンプレートは、
現在時刻は
{{#if oddSeconds}}
<span style="color: green;">{{dateString}}</span>
{{else}}
<span>{{dateString}}</span>
{{/if}}
です。
このテンプレートに対応するJavaScriptファイルは以下のとおりです。テンプレート内で使用されているoddSeconds
、dateString
といった式の値を返します。
if (Meteor.isClient) {
// 現在の秒が奇数かどうかを返す
Template.currentTime.oddSeconds = function() {
return new Date().getSeconds() % 2 === 1;
};
// 現在の日時を文字列にして返す
Template.currentTime.dateString = function() {
var date = new Date();
return date.getFullYear() + '年' + (date.getMonth() + 1) + '月' + date.getDate() + '日 '
+ date.getHours() + '時' + date.getMinutes() + '分' + date.getSeconds() + '秒';
};
}
#ifブロックのサンプルは以下からダウンロードできます。ちなみに、
#unlessブロック
#ifと逆の意味を持つブロックです。上の#ifのサンプルを#unlessで書きなおすと、
現在時刻は
{{#unless oddSeconds}}
<span>{{dateString}}</span>
{{else}}
<span style="color: green;">{{dateString}}</span>
{{/unless}}
です。
#eachブロック
繰り返しを行うためのブロックです。配列をループ処理することができます。また、
たとえば、
<h1>フルーツ</h1>
<ul>
{{#each fruits}}
<li>{{this}}</li>
{{/each}}
</ul>
Template.fruitsList.fruits = ['バナナ', 'りんご', 'ぶどう', 'オレンジ'];
#eachブロックのサンプルは以下からダウンロードできます。
ブロックヘルパー関数を自作する
以上のようなブロック構造は、
たとえばここでは、reverseEach
というヘルパー関数を作ってみます。
<!-- 配列を引数に取り、逆順にループ処理する -->
{{#reverseEach fruits}}
<li>{{this}}
{{/reverseEach}}
registerHelper()
の第一引数は、options
という引数を取ります。
options
はfn
という関数プロパティを持ち、fn
の引数には、this
を表すオブジェクトを渡します。また関数の戻り値は、
Handlebars.registerHelper('reverseEach', function(items, options) {
var contents = [];
// 関数を逆順で処理する
for (var i = items.length - 1; i >= 0; i--) {
contents.push(options.fn(items[i]));
}
// テンプレート内部を実行した結果を、文字列として返す
return contents.join('');
});
また、options
引数は使用しません。以下は、Handlebars.
のコンストラクタに文字列を渡したものを返します。
Handlebars.registerHelper('strong', function(content) {
return new Handlebars.SafeString('<strong>' + content + '</strong>');
});
こうして作成したヘルパー関数は、{{strong 引数}}
と記述すると呼び出すことができます。上の#reverseEach
ブロックと同時に用いることもできます。
{{#reverseEach fruits}}
<li>{{strong this}}
{{/reverseEach}}
elseブロックを使用する
{{else}}というブロックを用いると、options
オブジェクトが持つinverse
メソッドを呼び出すとelse
ブロックの内容が実行されます。
以下のサンプルは、
// ifAppleというヘルパー関数を作成
Handlebars.registerHelper('ifApple', function(obj, options) {
var contents = [];
// りんごの場合はifブロック内を実行
if (obj == 'りんご') {
contents.push(options.fn(this));
}
// それ以外の場合はelseブロックを実行
else {
contents.push(options.inverse(this));
}
return contents.join('');
});
上のヘルパー関数を使用している例は以下になります。thisの値が'りんご'だった場合のみ強調されます。
{{#ifApple this}}
<li>{{strong this}}
{{else}}
<li>{{this}}
{{/ifApple}}
Meteor上でのヘルパー関数の作成
MeteorにおけるHandlebarsは、
Template.fruitsList.ifApple = function(obj, options) {
...
});
ヘルパー関数を自作したサンプルは、
まとめ
今回は、