# はじめに

# Handlebarsとは?

Handlebarsはシンプルなテンプレート言語です。

テンプレートと入力オブジェクトを使用して、HTMLまたはその他のテキスト形式を生成します。Handlebarsテンプレートは、Handlebars式が埋め込まれた通常のテキストのように見えます。

テンプレート
<p>{{firstname}} {{lastname}}</p>

Handlebars式は、`{{`、コンテンツ、`}}`で構成されます。テンプレートが実行されると、これらの式は入力オブジェクトの値に置き換えられます。

詳細:式

# インストール

Handlebarsをテストする最も速い方法は、*CDN*からロードしてHTMLファイルに埋め込むことです。

<!-- Include Handlebars from a CDN -->
<script src="https://cdn.jsdelivr.net/npm/handlebars@latest/dist/handlebars.js"></script>
<script>
  // compile the template
  var template = Handlebars.compile("Handlebars <b>{{doesWhat}}</b>");
  // execute the compiled template and print the output to the console
  console.log(template({ doesWhat: "rocks!" }));
</script>

警告

この方法は、小規模なページやテストに使用できます。実際の運用システムを対象とする場合は、Handlebarsを使用する他のいくつかの方法があります。

詳細:インストール

# 言語機能

# 単純式

前述のように、次のテンプレートは2つのHandlebars式を定義しています

テンプレート
<p>{{firstname}} {{lastname}}</p>

入力オブジェクトに適用される場合

入力 ...(SVG省略)
{
  firstname: "Yehuda",
  lastname: "Katz",
}

式は対応するプロパティに置き換えられます。結果は次のとおりです

出力 ...(SVG省略)
<p>Yehuda Katz</p>

# ネストされた入力オブジェクト

入力オブジェクトに他のオブジェクトまたは配列が含まれている場合があります。例えば

入力 ...(SVG省略)
{
  person: {
    firstname: "Yehuda",
    lastname: "Katz",
  },
}

このような場合、ドット表記を使用してネストされたプロパティにアクセスできます

テンプレート ...(SVG省略)
{{person.firstname}} {{person.lastname}}

詳細:式

いくつかの組み込みヘルパーを使用すると、現在のコンテキストをネストされたオブジェクトに変更できます。その後、このオブジェクトにルートオブジェクトであるかのようにアクセスできます

# 評価コンテキスト

組み込みのブロックヘルパー `each` と `with` を使用すると、現在の評価コンテキストを変更できます。

`with` ヘルパーはオブジェクトプロパティに飛び込み、そのプロパティにアクセスできるようにします

テンプレート ...(SVG省略)
{{#with person}}
{{firstname}} {{lastname}}
{{/with}}
入力 ...(SVG省略)
{
  person: {
    firstname: "Yehuda",
    lastname: "Katz",
  },
}

`each` ヘルパーは配列を反復処理し、単純なHandlebars式を介して各オブジェクトのプロパティにアクセスできるようにします。

テンプレート
<ul class="people_list">
  {{#each people}}
    <li>{{this}}</li>
  {{/each}}
</ul>
入力 ...
{
  people: [
    "Yehuda Katz",
    "Alan Johnson",
    "Charles Jolley",
  ],
}

詳細はこちら:組み込みヘルパー

# テンプレートコメント

コード内と同様に、Handlebarsコードでもコメントを使用できます。一般的にはある程度のロジックが含まれているため、これは良い習慣です。

コメントは結果の出力には含まれません。コメントを表示させたい場合は、HTMLコメントを使用してください。HTMLコメントは出力されます。

}} やその他の Handlebars トークンを含む必要があるコメントは、{{!-- --}} 構文を使用する必要があります。

テンプレート ...
{{! This comment will not show up in the output}}
<!-- This comment will show up as HTML-comment -->
{{!-- This comment may contain mustaches like }} --}}

# カスタムヘルパー

Handlebarsヘルパーは、テンプレート内の任意のコンテキストからアクセスできます。 `Handlebars.registerHelper` メソッドを使用してヘルパーを登録できます。

テンプレート ...
{{firstname}} {{loud lastname}}
準備スクリプト ...
Handlebars.registerHelper('loud', function (aString) {
    return aString.toUpperCase()
})

ヘルパーは、関数の `this` コンテキストとして現在のコンテキストを受け取ります。

テンプレート ...
{{#each people}}
   {{print_person}}
{{/each}}
準備スクリプト ...
Handlebars.registerHelper('print_person', function () {
    return this.firstname + ' ' + this.lastname
})

# ブロックヘルパー

ブロック式を使用すると、現在のコンテキストとは異なるコンテキストでテンプレートのセクションを呼び出すヘルパーを定義できます。これらのブロックヘルパーは、ヘルパー名の前に `#` を付けることで識別され、同じ名前の対応する閉じ括弧 `/` が必要です。HTMLリストを生成するヘルパーを考えてみましょう。

準備スクリプト ...
Handlebars.registerHelper("list", function(items, options) {
  const itemsAsHtml = items.map(item => "<li>" + options.fn(item) + "</li>");
  return "<ul>\n" + itemsAsHtml.join("\n") + "\n</ul>";
});

この例では、HTMLリストを生成する `list` というヘルパーを作成します。ヘルパーは、最初のパラメーターとして `people` を、2番目のパラメーターとして `options` ハッシュを受け取ります。 `options` ハッシュには `fn` という名前のプロパティが含まれており、通常の Handlebars テンプレートを呼び出すのと同じように、コンテキストを指定して呼び出すことができます。

実行すると、テンプレートは以下のようにレンダリングされます。

出力
<ul>
<li>Yehuda Katz</li>
<li>Carl Lerche</li>
<li>Alan Johnson</li>
</ul>

ブロックヘルパーは、else セクション(例えば、組み込みの if ヘルパーで使用される)を作成する機能など、より多くの機能を備えています。

ブロックヘルパーの内容は options.fn(context) を呼び出すとエスケープされるため、Handlebars はブロックヘルパーの結果をエスケープしません。エスケープすると、内部コンテンツが二重にエスケープされます!

詳細はこちら:ブロックヘルパー

# HTML エスケープ

Handlebars は元々 HTML を生成するために設計されたため、{{expression}} によって返される値をエスケープします。 Handlebars に値をエスケープさせたくない場合は、「トリプルスタッシュ」、{{{ を使用します。

テンプレート ...(SVG省略)
raw: {{{specialChars}}}
html-escaped: {{specialChars}}

2 行目の特殊文字はエスケープされます

出力 ...(SVG省略)
raw: & < > " ' ` =
html-escaped: &amp; &lt; &gt; &quot; &#x27; &#x60; &#x3D;

Handlebars は Handlebars.SafeString をエスケープしません。独自の HTML を生成するヘルパーを作成する場合は、通常、new Handlebars.SafeString(result) を返します。このような状況では、パラメータを手動でエスケープする必要があります。

準備スクリプト ...(SVG省略)
Handlebars.registerHelper("bold", function(text) {
  var result = "<b>" + Handlebars.escapeExpression(text) + "</b>";
  return new Handlebars.SafeString(result);
});

これは渡されたパラメータをエスケープしますが、レスポンスを安全としてマークするため、"トリプルスタッシュ" が使用されていない場合でも、Handlebars はそれをエスケープしようとしません。

警告

Handlebars は JavaScript 文字列をエスケープしません。インラインイベントハンドラなど、JavaScript を生成するために Handlebars を使用すると、クロスサイトスクリプティングの脆弱性につながる可能性があります。

# パーシャル

Handlebars パーシャルでは、共有テンプレートを作成することでコードを再利用できます。 registerPartial メソッドを使用してパーシャルを登録できます

準備スクリプト ...(SVG省略)
Handlebars.registerPartial(
    "person", 
    "{{person.name}} is {{person.age}} years old.\n"
)

次のテンプレートと入力

テンプレート ...(SVG省略)
{{#each persons}}
  {{>person person=.}}
{{/each}}
入力 ...(SVG省略)
{
  persons: [
    { name: "Nils", age: 20 },
    { name: "Teddy", age: 10 },
    { name: "Nelson", age: 40 },
  ],
}

は、次の結果を提供します

出力 ...(SVG省略)
  Nils is 20 years old.
  Teddy is 10 years old.
  Nelson is 40 years old.

詳細はこちら:パーシャル

# 組み込みヘルパー

Handlebars は、if 条件や each イテレータなど、さまざまな組み込みヘルパーを提供しています。

詳細はこちら:組み込みヘルパー

# API リファレンス

Handlebars は、アプリケーションとヘルパーのために、さまざまな API とユーティリティメソッドを提供しています。

詳細はこちら:API リファレンス

最終更新日: 2021/10/19 18:50:45