今回は、Meteorアプリケーションのビューを作成する上で必要とされるHandlebarsについて解説します。
前回お伝えした通り、MeteorのHTML内ではHandlebarsを用いたテンプレートが利用できます。MeteorにおけるHandlebarsは、Meteorと緊密に統合されており、特別なインストール作業などを必要とする事なく利用できます。
式の実行
前回もお伝えしていますが、テンプレート内では{{式}}
という構文で式を実行し、結果をテンプレート上に書き出すことができます。たとえば、「personName」という変数を参照するための記述は以下のようになります。
また、ピリオドを用いて入れ子になっている変数を参照することもできます。以下のコードを実行すると、personという変数のnameプロパティを参照します。
また、「../」というパス指定により、親のスコープ変数を参照することもできます。これはたとえば、すぐ後に説明するwith句とともに用いるなどの利用シーンが考えられます。
上のテンプレートに対応するJavaScriptコードは以下になります。
実行結果は以下のようになります。
サンプルは以下からダウンロードできます。
ブロック構造の使用
Handlebarsには、条件分岐や繰り返しを行うためのブロック構造が組み込みで提供されています。
こうしたブロック構造は、「{{#if}} {{/if}}」のように、 「#」で始まり「/」で終了するという形式を取ります。
#withブロック
#withブロックは、引数で渡した変数を現在のコンテキストに設定します。テンプレート内で、入れ子のメンバーが持つ数多くのプロパティにアクセスする場合などに便利です。
たとえば、以下の様なテンプレートがあるとします。date
は日時の情報を格納したオブジェクトです。
#withブロックを使用すると、以下のようにオブジェクトアクセスを簡略化して記述することができます。
#withブロックのサンプルは以下からダウンロードできます。
#ifブロック
条件分岐を行うためのブロックです。引数の真偽値に応じて、ブロック内を実行するかどうかが決定されます。
以下のテンプレートは、oddSecondsという式を評価した結果に応じて、実行されるブロックが変わります。また、見ておわかりの通り、間に{{else}}節を含めることができます。
このテンプレートに対応するJavaScriptファイルは以下のとおりです。テンプレート内で使用されているoddSeconds
、dateString
といった式の値を返します。
#ifブロックのサンプルは以下からダウンロードできます。ちなみに、サンプルは「秒の値が奇数の時は文字を緑にする」というもので、あまり意味はありません。
#unlessブロック
#ifと逆の意味を持つブロックです。上の#ifのサンプルを#unlessで書きなおすと、以下のようになります。サンプルのダウンロードはこちら(sample5-4.zip)。
#eachブロック
繰り返しを行うためのブロックです。配列をループ処理することができます。また、ループ内で「this」を用いると、配列の各要素を参照できます。
たとえば、以下のようなテンプレートとJavaScriptの組み合わせがあった場合、配列要素からなるリストが出力されます。
#eachブロックのサンプルは以下からダウンロードできます。
ブロックヘルパー関数を自作する
以上のようなブロック構造は、自作することも可能です。自作する際に必要な処理は、「ブロックヘルパー関数」(以下、ヘルパー関数)と呼ばれます。ヘルパー関数を定義するためには、Handlebars.registerHelper()という関数を使用してHandlebarsへの登録を行います。
たとえばここでは、関数を逆順にループ処理する(#eachの逆バージョン)ためのreverseEach
というヘルパー関数を作ってみます。
registerHelper()
の第一引数は、ブロック名を表す文字列、第二引数はヘルパー関数の本体です。ヘルパー関数は、テンプレート中で渡される引数に加えて、最後にoptions
という引数を取ります。
options
はfn
という関数プロパティを持ち、これを呼び出すことで、ブロック内部のテンプレートを評価・実行することができます。fn
の引数には、ブロック内部でthis
を表すオブジェクトを渡します。また関数の戻り値は、テンプレートを実行した結果となるHTML文字列です。
また、ブロック構造をとらないヘルパー関数を作ることもできます。その場合、最後のoptions
引数は使用しません。以下は、渡された文字列を強調するだけのヘルパー関数です。戻り値がHTMLエスケープ不要な文字列の場合は、Handlebars.SafeString
のコンストラクタに文字列を渡したものを返します。
こうして作成したヘルパー関数は、{{strong 引数}}
と記述すると呼び出すことができます。上の#reverseEach
ブロックと同時に用いることもできます。
elseブロックを使用する
{{else}}というブロックを用いると、if-elseのような「条件に合致しなかった場合の処理」を記述することが可能になります。ヘルパー関数上では、引数として渡されるoptions
オブジェクトが持つinverse
メソッドを呼び出すとelse
ブロックの内容が実行されます。
以下のサンプルは、引数に渡されたオブジェクトが'りんご'かどうかで実行されるブロックが切り替わるというものです。
上のヘルパー関数を使用している例は以下になります。thisの値が'りんご'だった場合のみ強調されます。
Meteor上でのヘルパー関数の作成
MeteorにおけるHandlebarsは、Meteorと緊密に統合されており、ヘルパー関数の定義を、Meteorが持つテンプレートシステムの上で行うことができます。上のヘルパー関数(ifApple)を、Templateに対するメンバー指定で作成した場合は以下のようになります(Templateについては前回の記事を参照してください)。
ヘルパー関数を自作したサンプルは、以下からダウンロードできます。
まとめ
今回は、Meteorのテンプレートを記述する上で、理解しておく必要があるHandlebarsについて解説しました。次回は、テンプレートに関する残りの話題として、テンプレート内にイベントハンドラを登録する仕組みや、テンプレートに関するAPIを紹介します。