# 介绍

# 什么是 Handlebars?

Handlebars 是简单的 模板语言

它使用模板和输入对象来生成 HTML 或其他文本格式。 Handlebars 模板看起来像带有嵌入 Handlebars 表达式的常规文本。

template
<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 的方法。

了解更多:安装

# 语言特性

# 简单的表达

如前所示,以下模板定义了两个 Handlebars 表达式

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

如果应用于输入对象

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

表达式将被相应的属性替换。 那么结果就是

output
<p>Yehuda Katz</p>

# 嵌套输入对象

有时,输入对象包含其他对象或数组。 例如:

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

在这种情况下,你可以使用点符号来访问嵌套属性

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

了解更多:表达式

一些内置辅助程序允许你将当前上下文更改为嵌套对象。 然后你可以像访问根对象一样访问该对象

# 评估上下文

内置的块辅助程序 eachwith 允许你更改当前的评估上下文。

with 辅助程序深入研究对象属性,让你可以访问其属性

template
{{#with person}}
{{firstname}} {{lastname}}
{{/with}}
input
{
  person: {
    firstname: "Yehuda",
    lastname: "Katz",
  },
}

each 辅助程序迭代一个数组,允许你通过简单的句柄表达式访问每个对象的属性。

template
<ul class="people_list">
  {{#each people}}
    <li>{{this}}</li>
  {{/each}}
</ul>
input
{
  people: [
    "Yehuda Katz",
    "Alan Johnson",
    "Charles Jolley",
  ],
}

了解更多:内置助手

# 模板注释

你可以在 Handlebars 代码中使用注释,就像在代码中一样。 由于通常存在一定程度的逻辑,因此这是一个很好的做法。

注释不会出现在结果输出中。 如果你希望显示注释,只需使用 HTML 注释,它们就会被输出。

任何必须包含 }} 或其他把手标记的注释都应使用 {{!-- --}} 语法。

template
{{! 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 方法注册助手。

template
{{firstname}} {{loud lastname}}
preparationScript
Handlebars.registerHelper('loud', function (aString) {
    return aString.toUpperCase()
})

辅助程序接收当前上下文作为函数的 this 上下文。

template
{{#each people}}
   {{print_person}}
{{/each}}
preparationScript
Handlebars.registerHelper('print_person', function () {
    return this.firstname + ' ' + this.lastname
})

# 块助手

块表达式允许你定义辅助程序,这些辅助程序将使用与当前不同的上下文调用模板的一部分。 这些块助手由助手名称前面的 # 标识,并且需要匹配的同名闭合胡须 /。 让我们考虑一个将生成 HTML 列表的助手:

preparationScript
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 的辅助程序来生成 HTML 列表。 辅助程序接收 people 作为其第一个参数,并接收 options 哈希作为其第二个参数。 options 哈希包含一个名为 fn 的属性,你可以使用上下文调用该属性,就像调用普通的 Handlebars 模板一样。

执行时,模板将渲染:

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

块助手具有更多功能,例如创建 else 部分的能力(例如,由内置 if 助手使用)。

由于当你调用 options.fn(context) 时,块助手的内容会被转义,因此 Handlebars 不会转义块助手的结果。 如果是这样,内部内容将被双重转义!

了解更多:块助手

# HTML 转义

因为它最初设计用于生成 HTML,所以 Handlebars 会对 {{expression}} 返回的值进行转义。 如果你不希望 Handlebars 转义某个值,请使用 "三个大括号"、{{{

template
raw: {{{specialChars}}}
html-escaped: {{specialChars}}

第二行中的特殊字符将被转义:

output
raw: & < > " ' ` =
html-escaped: &amp; &lt; &gt; &quot; &#x27; &#x60; &#x3D;

Handlebars 也不转义 Handlebars.SafeString。 如果你编写一个生成自己的 HTML 的辅助程序,你通常会希望返回 new Handlebars.SafeString(result)。 在这种情况下,你将需要手动转义参数。

preparationScript
Handlebars.registerHelper("bold", function(text) {
  var result = "<b>" + Handlebars.escapeExpression(text) + "</b>";
  return new Handlebars.SafeString(result);
});

这将转义传入的参数,但将响应标记为安全,因此即使不使用 "三个大括号",Handlebars 也不会尝试转义它。

警告

Handlebars 不会转义 JavaScript 字符串。 使用 Handlebars 生成 JavaScript(例如内联事件处理程序)可能会导致跨站点脚本漏洞。

# 局部

Handlebars 部分允许通过创建共享模板来重用代码。 你可以使用 registerPartial 方法注册部分:

preparationScript
Handlebars.registerPartial(
    "person", 
    "{{person.name}} is {{person.age}} years old.\n"
)

以下模板和输入:

template
{{#each persons}}
  {{>person person=.}}
{{/each}}
input
{
  persons: [
    { name: "Nils", age: 20 },
    { name: "Teddy", age: 10 },
    { name: "Nelson", age: 40 },
  ],
}

然后将提供以下结果:

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

了解更多:局部

# 内置助手

Handlebars 提供了各种内置辅助程序,例如 if 条件和 every 迭代器。

了解更多:内置助手

# API 参考

Handlebars 为应用和助手提供了各种 API 和实用方法。

了解更多:API 参考

Last Updated: 2023/9/14 11:12:03