语法规范

语法规范

本文档概述了 Edge 模板语法规范。你可以参考本文档来更好地理解 Edge 的内部实现,或者为你喜欢的代码编辑器创建语法高亮器。

目标

Edge 的主要目标不是给模板层引入任何新方言,而是处处使用 JavaScript。

  1. 让语法更贴近 JavaScript。
  2. 应易于输入和理解。
  3. Edge 应能配合任意标记语言工作,而不仅仅是 HTML。
  4. 生成指向原始源文件及行号的错误堆栈。

原语(Primitives)

Edge 建立在两个核心原语之上,即:

  • 花括号:熟悉的花括号 {{ }} 用于求值 JavaScript 表达式。
  • Edge 标签:Edge 标签以 @ 符号开头,后跟标签名。标签可以接收属性,并拥有由开始与结束语句包裹的子元素。

花括号

Edge 使用熟悉的花括号 {{ }} 来求值 JavaScript 表达式。表达式的输出会被拼接进输出字符串。例如:

Hello {{ username }}!

假设 username 为 Virk,输出将是

Hello Virk

多行表达式

表达式可以跨越多行。例如:

Hello {{
users.map((user) => {
return user.username
})
}}

由于模板的输出始终是 string,JavaScript 表达式的输出也会被转换为字符串。

在上面的示例中,JavaScript 表达式返回一个数组,并会被转换为以逗号分隔的字符串。其输出等同于编写以下 JavaScript 代码。

String(users.map((user) => {
return user.username
}))

你可以使用 JavaScript 的 Array.join 方法自行将数组转换为字符串。

Hello {{
users.map((user) => {
return user.username
}).join(', ')
}}

转义后的 HTML 输出

Edge 会对使用 mustache 花括号渲染的 JavaScript 表达式输出进行 HTML 转义。

给定以下 HTML 字符串

{{
'<span style="color: red">This should be red.</span>'
}}

输出将是

&lt;span style="color: red"&gt;This should be red.&lt;/span&gt;

如果你想原样渲染 HTML,可以使用三重花括号,或者使用 html.safe 全局方法。

{{{
'<span style="color: red">This should be red.</span>'
}}}
{{
html.safe(
'<span style="color: red">This should be red.</span>'
)
}}

转义花括号

假设你将 Edge 与同样使用花括号进行插值的前端模板引擎结合使用。在这种情况下,你可以使用 @ 符号来告知 Edge 跳过给定的语句。例如:

输入
Edge should not parse @{{ username }}
输出
Edge should not parse {{ username }}

Edge 标签

Edge 标签用于为模板层添加丰富的功能。条件语句、循环、组件和局部模板等功能都是使用 标签 API 实现的。

标签必须独占一行书写,周围不能有其他内容。这是我们有意为之的设计,以便在编译器层面让标签 API 易于扫描。你始终可以使用花括号在同一行内混合内容 + JavaScript 代码。

标签进一步细分为以下子类别。

块级标签

块级标签拥有开始与结束语句,并在其中容纳内容。@if 标签就是一个块级标签。

@if(someCondition)
If block content
@end

你可以通过在标签名前加 ! 运算符来自动闭合块级标签。

自动闭合
@!component('button', { size: 'large' })
显式闭合
@component('button', { size: 'large' })
@end

内联标签

内联标签不接受主体内容,因此你无需显式闭合它。@include 标签就是一个内联标签。

@include('partials/some-file')

无参数的标签

标签也可以不带参数书写。例如 @debugger 标签。但是,如果一个标签接受参数,那么你必须始终像调用函数一样调用它。

@debugger

吞掉换行

标签应始终与块级内容一起使用,因为它们会在两段文本之间创建一个换行分隔符。

然而,如果你在某些换行会改变输出含义或使其无效的场景中使用标签,就必须在标签后追加 ~ 符号。

不加波浪号

Hello
@let(username = 'virk')
{{ username }}
Hello
virk

加上波浪号

Hello
@let(username = 'virk')~
{{ username }}
Hello virk

注释

你可以通过将文本包裹在 {{-- --}} 块中来编写 Edge 注释。

{{-- Inline before --}} Hello {{-- Inline after --}}
{{--
This is a multi-line comment.
--}}

示例

无效 ❌ 有效 ✅
@if
(
username
)
@if(username)
@if(username) Hello @endif
@if(username)
Hello
@end
@if(
username
:) <p> Hello </p>
@endif
@if(
username
)
<p> Hello </p>
@end
无效 ❌ 有效 ✅
@! component('button')
@!component('button')
@!component
('button', {
type: 'primary'
})
@!component(
'button',
{
type: 'primary'
}
)