# 表达式

Handlebars 表达式是 Handlebars 模板的基本单元。 你可以在 {{mustache}} 中单独使用它们,将它们传递给 Handlebars 辅助程序,或者将它们用作哈希参数中的值。

# 基本用法

Handlebars 表达式是用双大括号 {{}} 括起来的一些内容。 在下面的模板中,firstname 是一个用双大括号括起来的变量,它被称为一个表达式。

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

如果以下输入对象应用于模板

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

表达式被编译以产生如下输出:

output
<p>Yehuda Katz</p>

# 路径表达式

Handlebars 表达式也可以是点分隔的路径。

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

此表达式在输入对象中查找 person 属性,然后在 person 对象中查找 firstnamelastname 属性。

Pass the below input object to the template

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

Output will be generated as below

output
Yehuda Katz

Handlebars 还支持已弃用的 / 语法,因此你可以将上述模板编写为:

template
{{person/firstname}} {{person/lastname}}

# 改变上下文

一些助手(例如 #with#each)允许你深入研究嵌套对象。 当你在路径中包含 ../ 段时,Handlebars 将变回父上下文。

template
{{#each people}}
    {{../prefix}} {{firstname}} 
{{/each}}

即使在注释上下文中打印名称,它仍然可以返回到主上下文(根对象)以检索前缀。

警告

../ 将解析为的确切值根据调用该块的辅助程序而有所不同。 仅当上下文发生变化时才需要使用 ../{{#each}} 等帮手的子级需要使用 ../,而 {{#if}} 等帮手的子级则不需要。

{{permalink}}
{{#each comments}}
  {{../permalink}}

  {{#if title}}
    {{../permalink}}
  {{/if}}
{{/each}}

在此示例中,上述所有内容都引用相同的前缀值,即使它们位于不同的块内。 此行为是 Handlebars 4 中的新行为; 发行说明 讨论先前的行为以及迁移计划。 Handlebars 还允许通过 this 引用解决辅助程序和数据字段之间的名称冲突:

# 字面量片段

标识符可以是任何 unicode 字符,但以下字符除外:

空白 ! " # % & ' ( ) * + , . / ; < = > @ [ \ ] ^ ` { | } ~

此外,单词 truefalsenullundefined 只允许出现在路径表达式的第一部分中。

要引用不是有效标识符的属性,可以使用段字面量表示法 [。 你不能在路径字面量中包含结束 ],但允许使用所有其他字符。

JavaScript 风格的字符串 "' 也可以用来代替 [ 对。

template
{{!-- wrong: {{array.0.item}} --}}
correct: array.[0].item: {{array.[0].item}}

{{!-- wrong: {{array.[0].item-class}} --}}
correct: array.[0].[item-class]: {{array.[0].[item-class]}}

{{!-- wrong: {{./true}}--}}
correct: ./[true]: {{./[true]}}

# HTML-escaping

在 Handlebars 中,{{expression}} 返回的值是 HTML 转义的。 假设,如果表达式包含 &,则返回的 HTML 转义输出将生成为 &amp;。 如果你不希望 Handlebars 转义值,请使用 "三个大括号"、{{{

在下面的模板中,你可以了解如何生成 HTML 转义和原始输出。

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

将特殊字符传递给模板

input
{ specialChars: "& < > \" ' ` =" }

"三个大括号" ({{{) 括起来的表达式生成原始输出。 否则,将生成 HTML 转义输出,如下所示。

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

# 助手

助手可用于实现不属于 Handlebars 语言本身的功能。

可以在运行时通过 Handlebars.registerHelper 注册助手,例如为了将字符串的所有字符大写。

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

Handlebars 辅助程序调用是一个简单的标识符,后跟零个或多个参数(用空格分隔)。 每个参数都是一个 Handlebars 表达式,其计算方式与上面 "基本用法" 中所述的完全相同:

template
{{firstname}} {{loud lastname}}

在本例中,loud 是助手的名称,lastname 是助手的参数。 该模板会将输入的 lastname 属性大写:

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

# 防止助手返回值的 HTML 转义

当你的辅助程序返回 Handlebars.Safestring 的实例时,即使使用 {{ 而不是 {{{ 调用该辅助程序,返回值也不会转义。 你必须注意使用 Handlebars.escapeExpression 正确转义所有参数。

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

# 使用多个参数的助手

让我们看看带有两个参数的助手的另一个示例

template
{{link "See Website" url}}

在这种情况下,Handlebars 将向链接助手传递两个参数: 来自下面提供的输入 people 对象的字符串 See Websitepeople.url 的值。

input
{ url: "https://yehudakatz.com/" }

辅助函数 link 用于生成脚本中描述的超链接。

preparationScript
Handlebars.registerHelper("link", function(text, url) {
      var url = Handlebars.escapeExpression(url),
          text = Handlebars.escapeExpression(text)
          
     return new Handlebars.SafeString("<a href='" + url + "'>" + text +"</a>");
});

我们将使用输入参数获得输出

output
<a href='https://yehudakatz.com/'>See Website</a>

在上面的示例中,你可以根据 people.text 的值对动态文本使用完全相同的辅助程序:

template
{{link people.text people.url}}
input
{
  people: {
    firstname: "Yehuda",
    lastname: "Katz",
    url: "https://yehudakatz.com/",
    text: "See Website",
  },
}

# 字面量参数

辅助程序调用还可以将字面量值作为参数参数或哈希参数传递给它们。 支持的字面量包括数字、字符串、truefalsenullundefined

template
{{progress "Search" 10 false}}
{{progress "Upload" 90 true}}
{{progress "Finish" 100 false}}

# 使用哈希参数的助手

Handlebars 向辅助程序提供附加元数据(例如哈希参数)作为最终参数。

template
{{link "See Website" href=person.url class="person"}}

在该模板中,最后一个参数 href=people.url class="people" 是发送给助手的哈希参数。

哈希参数中的键必须是简单标识符,值是 Handlebars 表达式。 这意味着值可以是简单的标识符、路径或字符串。

如果我们将以下输入传递给模板,则可以从 person 对象中获取 person.url 的值。

input
{
  person: {
    firstname: "Yehuda",
    lastname: "Katz",
    url: "https://yehudakatz.com/",
  },
}

如下面的辅助程序脚本中所述,可以从最后一个参数 options 获取哈希参数,以便在辅助程序中进行进一步处理。

preparationScript
Handlebars.registerHelper("link", function(text, options) {
    var attributes = [];

    Object.keys(options.hash).forEach(key => {
        var escapedKey = Handlebars.escapeExpression(key);
        var escapedValue = Handlebars.escapeExpression(options.hash[key]);
        attributes.push(escapedKey + '="' + escapedValue + '"');
    })
    var escapedText = Handlebars.escapeExpression(text);
    
    var escapedOutput ="<a " + attributes.join(" ") + ">" + escapedText + "</a>";
    return new Handlebars.SafeString(escapedOutput);
});

上述助手的输出如下所示

output
<a class="person" href="https://yehudakatz.com/">See Website</a>

Handlebars 还提供了一种通过模板块调用助手的机制。 然后,块助手可以使用它选择的任何上下文调用该块零次或多次。

了解更多:块助手

# 消除助手调用和属性查找的歧义

如果助手以与输入对象的属性相同的名称注册,则助手的优先级高于输入属性。 如果你想解析输入属性,则可以在其名称前添加 ./this.(或已弃用的 this/

template
helper: {{name}}
data: {{./name}} or {{this/name}} or {{this.name}}
input
{ name: "Yehuda" }
preparationScript
Handlebars.registerHelper('name', function () {
    return "Nils"
})

# 子表达式

Handlebars 提供对子表达式的支持,它允许你在单个 Mustache 中调用多个辅助程序,并将内部辅助程序调用的结果作为参数传递给外部辅助程序。 子表达式由括号分隔。

{{outer-helper (inner-helper 'abc') 'def'}}

在这种情况下,inner-helper 将使用字符串参数 'abc' 进行调用,而 inner-helper 函数返回的任何内容都将作为第一个参数传递给 outer-helper(而 'def' 将作为第二个参数传递给 outer-helper)。

# 空白控制

通过在大括号中添加 ~ 字符,可以从任何 Mustache 语句的任一侧省略模板空白。 应用时,该侧的所有空格都将被删除,直到该侧的第一个把监视达式或非空格字符。

{{#each nav ~}}
  <a href="{{url}}">
    {{~#if test}}
      {{~title}}
    {{~^~}}
      Empty
    {{~/if~}}
  </a>
{{~/each}}

在此背景下:

{
  nav: [{ url: "foo", test: true, title: "bar" }, { url: "bar" }];
}

结果输出没有换行符和格式化空白:

<a href="foo">bar</a><a href="bar">Empty</a>

这扩展了剥离 "standalone" 辅助程序行的默认行为(仅是块辅助程序、注释或部分和空格)。

{{#each nav}}
  <a href="{{url}}">
    {{#if test}}
      {{title}}
    {{^}}
      Empty
    {{/if}}
  </a>
{{~/each}}

将渲染

<a href="foo">
  bar
</a>
<a href="bar">
  Empty
</a>

# 转义 Handlebars 表达式

Handlebars 内容可以通过以下两种方式之一进行转义:内联转义或原始块助手。 通过在胡子块前面添加 \ 前缀来创建内联转义。 原始块是使用 {{{{ 小胡子括号创建的。

\{{escaped}}
{{{{raw}}}}
  {{escaped}}
{{{{/raw}}}}

原始块的操作方式与其他 块助手 相同,区别在于子内容被视为字面量字符串。

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