# 介绍

¥Introduction

# 什么是 Handlebars?

¥What is Handlebars?

Handlebars 是一种简单的模板语言。

¥Handlebars is a simple templating language.

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

¥It uses a template and an input object to generate HTML or other text formats. Handlebars templates look like regular text with embedded Handlebars expressions.

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

Handlebars 表达式是 {{、一些内容、后跟 }}。执行模板时,这些表达式将替换为输入对象中的值。

¥A handlebars expression is a {{, some contents, followed by a }}. When the template is executed, these expressions are replaced with values from an input object.

了解更多:表达式

¥!buttonLearn More: Expressions

# 安装

¥Installation

测试 Handlebars 的最快方法是从 CDN 加载它并将其嵌入 HTML 文件中。

¥The fastest way to test Handlebars is to load it from a CDN and embed it in an HTML file.

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

¥This method can be used for small pages and for testing. There are several other ways to use Handlebars, when you target real production systems.

了解更多:安装

¥!buttonLearn more: Installation

# 语言特性

¥Language features

# 简单的表达

¥Simple expressions

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

¥As shown before, the following template defines two Handlebars expressions

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

如果应用于输入对象

¥If applied to the input object

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

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

¥the expressions will be replaced by the corresponding properties. The result is then

output
<p>Yehuda Katz</p>

# 嵌套输入对象

¥Nested input objects

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

¥Sometimes, the input objects contains other objects or arrays. For example:

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

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

¥In such a case, you can use a dot-notation to gain access to the nested properties

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

了解更多:表达式

¥!buttonLearn more: Expressions

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

¥Some built-in helpers allow you to change the current context to a nested object. You can then access this object as if it were the root object

# 评估上下文

¥Evaluation context

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

¥The built-in block-helpers each and with allow you to change the current evaluation context.

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

¥The with-helper dives into an object-property, giving you access to its properties

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

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

¥The each-helper iterates an array, allowing you to access the properties of each object via simple handlebars expressions.

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

了解更多:内置助手

¥!buttonLearn more: Built-in helpers

# 模板注释

¥Template comments

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

¥You can use comments in your handlebars code just as you would in your code. Since there is generally some level of logic, this is a good practice.

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

¥The comments will not be in the resulting output. If you'd like the comments to show up just use HTML comments, and they will be output.

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

¥Any comments that must contain }} or other handlebars tokens should use the {{!-- --}} syntax.

template
{{! This comment will not show up in the output}}
<!-- This comment will show up as HTML-comment -->
{{!-- This comment may contain mustaches like }} --}}

# 自定义助手

¥Custom Helpers

可以从模板中的任何上下文访问 Handlebars 助手。你可以使用 Handlebars.registerHelper 方法注册助手。

¥Handlebars helpers can be accessed from any context in a template. You can register a helper with the Handlebars.registerHelper method.

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

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

¥Helpers receive the current context as the this-context of the function.

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

# 块助手

¥Block Helpers

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

¥Block expressions allow you to define helpers that will invoke a section of your template with a different context than the current. These block helpers are identified by a # preceeding the helper name and require a matching closing mustache, /, of the same name. Let's consider a helper that will generate an HTML list:

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 模板一样。

¥The example creates a helper named list to generate our HTML list. The helper receives the people as its first parameter, and an options hash as its second parameter. The options hash contains a property named fn, which you can invoke with a context just as you would invoke a normal Handlebars template.

执行时,模板将渲染:

¥When executed, the template will render:

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

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

¥Block helpers have more features, such as the ability to create an else section (used, for instance, by the built-in if helper).

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

¥Since the contents of a block helper are escaped when you call options.fn(context), Handlebars does not escape the results of a block helper. If it did, inner content would be double-escaped!

了解更多:块助手

¥!buttonLearn More: Block Helpers

# HTML 转义

¥HTML Escaping

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

¥Because it was originally designed to generate HTML, Handlebars escapes values returned by a {{expression}}. If you don't want Handlebars to escape a value, use the "triple-stash", {{{.

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

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

¥The special characters in the second line will be escaped:

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

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

¥Handlebars will not escape a Handlebars.SafeString. If you write a helper that generates its own HTML, you will usually want to return a new Handlebars.SafeString(result). In such a circumstance, you will want to manually escape parameters.

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

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

¥This will escape the passed in parameters, but mark the response as safe, so Handlebars will not try to escape it even if the "triple-stash" is not used.

警告

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

¥Handlebars does not escape JavaScript strings. Using Handlebars to generate JavaScript, such as inline event handlers, could potentially lead to cross-site scripting vulnerabilities.

# 局部

¥Partials

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

¥Handlebars partials allow for code reuse by creating shared templates. You can register a partial using the registerPartial-method:

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

以下模板和输入:

¥The following template and input:

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

然后将提供以下结果:

¥will then provide the following result:

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

了解更多:局部

¥!buttonLearn More: Partials

# 内置助手

¥Built-In Helpers

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

¥Handlebars offers a variety of built-in helpers such as the if conditional and each iterator.

了解更多:内置助手

¥!buttonLearn More: Built-In Helpers

# API 参考

¥API Reference

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

¥Handlebars offers a variety of APIs and utility methods for applications and helpers.

了解更多:API 参考

¥!buttonLearn More: API Reference

Last Updated: 2024/3/9 17:51:41