Handlebars 簡介

hjb2722404發表於2020-12-11

Handlebars 是什麼

Handlebars 是一種簡單的模板語言。

它使用模板與傳入的物件來生成HTML 或者其他文字格式。

Handlebars 模板看起來像是嵌入了handlebars 表示式的普通文字。

<p> {{firstname}} {{lastname}}</p>

一個handlebars表示式是使用兩對尖括號包裹一些內容:{{some contet}}。當模板被執行時,表示式中的內容將被來自輸入的物件中的值所替換。

安裝

使用Handlebars最快的方式就是從CDN 載入它並且將它嵌入HTML檔案。

<!--從CDN引入Handlebars -->
<script src="https://cdn.jsdelivr.net/npm/handlebars@latest/dist/handlebars.js"></script>
<script>
  // 編譯模板
  var template = Handlebars.compile("Handlebars <b>{{doesWhat}}</b>");
  // 執行編譯後的模板並將內容輸出到控制檯
  console.log(template({ doesWhat: "rocks!" }));
</script>

語言特性

簡潔的表示式

正如前面所展示的,下面的模板定義了兩個Handlebars 表示式

<p> {{firstname}} {{lastname}}</p>

如果輸入的資料物件如下:

{
  firstname: "Yehuda",
  lastname: "Katz"
}

表示式將被對應的屬性所替換,結果如下:

<p> Yehuda Katz</p>

可巢狀的資料物件

有時,輸入的資料物件還可以包含巢狀其它陣列或物件,比如:

{
  person: {
    firstname: "Yehuda",
    lastname: "Katz"
  }
}

在這個例子中,你可以使用點語法來訪問巢狀的屬性

{{person.firstname}} {{person.lastname}}

可變執行上下文

內建的塊輔助器each,with 允許您更改當前的執行上下文

with 輔助器潛入一個物件的屬性,讓你可以訪問它的屬性

{{#with person}}
{{firstname}} {{lastname}}
{{/with}}
{
	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註釋就可以了。

任何必須包含}}或其他handlebars標記的註釋都應該使用{{!- - - - -}}語法

{{! 這條註釋將不會輸出}}
<!-- 這條註釋將作為HTML註釋顯示出來 -->
{{!-- 這條註釋可能包含 }} --}}

自定義輔助器

Handlebars輔助器可以在模板的任意上下文位置訪問,你可以使用Handlebars.registerHelper方法來註冊一個輔助器。

{{firstname}} {{loud lastname}}
Handlebars.registerHelper('loud', function (aString) {
    return aString.toUpperCase()
})
{
  firstname: "Yehuda",
  lastname: "Katz"
}

輸出:

Yehuda KATZ

輔助器可以接收最近的上下文來作為this的值:

{{#each people}}
   {{print_person}}
{{/each}}
Handlebars.registerHelper('print_person', function () {
    return this.firstname + ' ' + this.lastname
})
{
  people: [
    {
      firstname: "Nils",
      lastname: "Knappmeier"
    },
    {
      firstname: "Yehuda",
      lastname: "Katz"
    }
  ]
}

輸出結果:

Nils Knappmeier
Yehuda Katz

區塊輔助器

區塊表示式允許你定義輔助器,這些輔助器將使用與當前上下文不同的上下文來呼叫模板的一部分。

這些區塊輔助器在輔助物件名稱之前以# 標識,並且需要匹配後面具有相同名稱的閉合符號/。讓我們來看一個將生成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>";
});
{{#list people}}{{firstname}} {{lastname}}{{/list}}
{
  people: [
    {
      firstname: "Yehuda",
      lastname: "Katz"
    },
    {
      firstname: "Carl",
      lastname: "Lerche"
    },
    {
      firstname: "Alan",
      lastname: "Johnson"
    }
  ]
}

輸出結果:

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

這個例子中,我們建立了一個名為list的輔助器,我們用它來生成HTML列表。這個輔助器接收people 作為它的第一個引數,接收型別為雜湊的options作為第二個引數。在options 中包含一個名為fn的屬性, 您可以通過上下文呼叫它,就像呼叫普通的Handlebars模板一樣。

區塊輔助器還具有很多特性,比如建立一個else 區塊(使用內建的if輔助器)

由於區塊輔助器的內容在呼叫options.fn(context)時被轉義,所以Handlebars不會轉義區塊輔助器的結果。否則,內部內容將會被重複轉義。

HTML轉義

因為Handlebars最初被設計成生成HTML,所以它通過{{expression}}返回的值來轉義。如果你不想轉義一個值,使用"三對尖括號",{{{

不轉義: {{{specialChars}}}
HTML轉義後: {{specialChars}}
{ specialChars: "& < > \" ' ` =" }

輸出結果:

不轉義: & < > " ' ` =
HTML轉義後: &amp; &lt; &gt; &quot; &#x27; &#x60; &#x3D;

Handlebars 不會轉義一個Handlebars.SafeString。如果你寫了一個輔助器去生成HTML,你可以返回一個new Handlebars.SafeString(result)。在這種情況下,需要手動轉義引數。

{{bold text}}
Handlebars.registerHelper("bold", function(text) {
  var result = "<b>" + Handlebars.escapeExpression(text) + "</b>";
  return new Handlebars.SafeString(result);
});
{ text: "Isn't this great?" }

輸出結果:

<b>Isn&#x27;t this great?</b>

這將轉義傳入的引數,但將響應標記為安全,因此即使沒有使用“三重尖括號”,Handlebars也不會試圖轉義它

片段

Handlebars 的片段允許你建立共享模板來實現程式碼重用。你可以使用registerPartial方法來註冊一個片段

Handlebars.registerPartial(
    "person", 
    "{{person.name}} is {{person.age}} years old.\n"
)
{{#each persons}}
  {{>person person=.}}
{{/each}}
{
  persons: [
    { name: "Nils", age: 20 },
    { name: "Teddy", age: 10 },
    { name: "Nelson", age: 40 }
  ]
}

輸出:

 Nils is 20 years old.
  Teddy is 10 years old.
  Nelson is 40 years old.

內建輔助器

Handlebars提供了豐富的內建輔助器,比如if條件輔助器和each 迭代輔助器。

API指南

Handlebars為應用和輔助器提供了豐富的API 和實用的方法