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
不会转义区块辅助器的结果。否则,内部内容将会被重复转义。
因为Handlebars
最初被设计成生成HTML
,所以它通过{{expression}}返回的值来转义。如果你不想转义一个值,使用"三对尖括号",{{{
。
不转义: {{{specialChars}}}
HTML转义后: {{specialChars}}
{ specialChars: "& < > \" ' ` =" }
输出结果:
不转义: & < > " ' ` =
HTML转义后: & < > " ' ` =
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'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
迭代辅助器。
Handlebars
为应用和辅助器提供了丰富的API
和实用的方法