Scriban是一个快速、强大、安全且轻量级的模板引擎,同时兼容liquid语法规则。

项目地址:https://github.com/scriban/scriban

这个文档是语言语法的中文翻译

原文地址:https://github.com/scriban/scriban/blob/master/doc/language.md

翻译人:Frank.Cui

Email:frank@mondol.info

本文档描述了Scriban语言的语法(在{{}}内)

在纯脚本环境中,语言的规则是相同的。

注意:本文档不描述liquid语言,如有需求可查看它的官方[liquid website](https://shopify.github.io/liquid/)

模板中有3种类型的文本块

  • 代码块:包含Scriban代码语句
  • 文本块:按原样输出的普通文本
  • 转义块:可以转义代码块的文本块

代码块

{{}}括起来的文本是 Scriban的代码块,将由 Scriban 模板引擎进行执行。

代码中块能包含:

  • 单行表达式语句:

    {{ name }}
  • 或多行语句:
{{
if !name
name = "default"
end
name
}}
  • 或由分号(;)分隔的多条语句,某些用例中格式更紧凑:

    {{if !name; name = "default"; end; name }}

在代码块中,空白字符对解析没有影响,但每个语句后面的行尾字符除外。 唯一的例外是使用空格来区分数组索引器和数组初始值设定项。

此外,当语句是表达式(但不是赋值表达式)时,表达式的结果将显示在模板的输出中:

{{
x = 5 # 变量赋值,不会输出任何内容
x # 这个表达式输出5
x + 1 # 这个表达式输出6
}}
56

请注意,在上面的示例中,5 和 6 之间没有换行,因为我们位于代码块内。

但您仍然可以在代码块内使用\n来主动换行,或者可以使用混合代码和文本块:

{{ x = 5 }}
{{ x }}
{{ x + 1 }}
5
6

文本块

否则,任何文本都将被视为文本块并不加修改地输出。

Hello this is {{ name }}, welcome to scriban!
______________ _____________________
文本块 文本块

转义块

任何代码和文本块都可以通过用 {%{}%}括起来来转义,以生成文本块。

例如下面的转义:

输入:{%{Hello this is {{ name }}}%}

输出:Hello this is {{ name }}

如果要转义转义块,可以增加起始块和结束块中的 % 数量:

输入:{%%{This is an escaped block: }%} here}%%}

输出:This is an escaped block: }%} here

这允许有效地嵌套逃生块并且仍然能够逃脱它们。

例如:{%%%%{ will require an ending }%%%%}

空白控制

默认情况下,代码/转义块之前或之后的任何空格(包括Tab、换行符)都会按原样复制到输出。

Scriban 提供了两种控制空白的模式:

使用字符-

{{--}}表示贪婪模式会删除所有空白字符(包括换行符)。

例如:删除左侧的空白

This is a <
{{- name}}> text
This is a <foo> text

例如:删除右侧的空白

This is a <{{ name -}}
> text:
This is a <foo> text

例如:删除左、右的空白

This is a <
{{- name -}}
> text:
This is a <foo> text

使用字符~

{{~~}}表示非贪婪模式会删除所有空白字符(换行符除外)。

当您只想在一行上使用 scriban 语句,但希望该行完全被使用时,此模式非常方便,从输出中删除,但保持该行前后的空格完好无损。

在下面的示例中,我们想要完全删除行 {{~ for products in products ~}}{{~ end ~}},但我们想要保留开头 <li> 的缩进。

使用贪婪模式( {{--}})会删除所有空格和行,并将结果放在一行上。

<ul>
{{~ for product in products ~}}
<li>{{ product.name }}</li>
{{~ end ~}}
</ul>
<ul>
<li>Orange</li>
<li>Banana</li>
<li>Apple</li>
</ul>

组合控制

  • ~- 也可以与转义块一起使用

    • 例如: {%%{~``~}%%}{%%{-``-}%%}
  • ~- 也可以混用
    • 例如:{{- name ~}}{{~ name -}}
  • 也可以与无控制符混用
    • 例如:{{ name ~}}{{~ name }}

注释

在代码块内,Scriban支持单行注释 # 和多行注释 ##

{{ name # 这是单行注释 }}
{{ ## 这是
多行
注释 ## }}

正如您所看到到的,单行和多行注释都可以通过代码块退出标记(}})来关闭。

数据类型

字符串

Scriban 支持3种类型的字符串

常规字符串

用双引号"..."或单引号'...'括起来的常规字符串。常规字符串支持多行并将支持以下转义字符:

  • \' 单引号
  • \" 双引号
  • \\ 反斜杠
  • \n 换行
  • \r 回行
  • \t tab
  • \b 退格键
  • \f 换页
  • \uxxxx 其中 xxxx 是 unicode 十六进制代码编号 0000ffff
  • \x00-\xFF 范围从 0x000xFF 的十六进制

原始字符串

用反引号...括起来的字符串,会原样输出,不会处理转义,例如可用于正则表达式场景:

{{ "this is a text" | regex.split `\s+` }}
[this, is, a, text]

内插字符串

$开头并用双引号 $"..." 或单引号 $'...' 括起来的内插字符串。

内插字符串中可以使用变量、表达式。

{{ $"this is an interpolated string with an expression {1 + 2} and a substring {"Hello"}" }}
this is an interpolated string with an expression 3 and a substring Hello

数值

与Javascript中的数值是一样的,例如:{{ 100 }}

整数

  • 10进制整数:100, 1e3
  • 16进制整数:0x1ef
  • 无符号整数:0x80000000u

浮点数

  • 100.0, 1.0e3, 1.0e-3
  • 32位:100.0f
  • 64位:100.0d
  • 128高精度:100.0m

布尔

布尔值 {{ true }}{{ false }}

{{ true }}
{{ false }}
true
false

null

与Javascript里的null是一样的,例如:{{ null }}

当解析为字符串输出时,null值将输出空字符串:

{{ null }}

变量

Scriban 支持全局变量局部变量的概念。

全局变量

全局变量以字母或下划线 _ 开头,后面跟着字母 A-Z a-z、数字 0-9、下划线 _,例如:{{ name }}

以下是有效的变量名称:

  • var
  • var9
  • _var

局部变量

局部变量是以 $ 开头的标识符(例如:{{ $name }}),局部变量只能在同一页面或函数体内访问。

单独的特殊局部变量 $ 是一个数组,其中包含传递给当前函数或页页的参数。

特殊局部变量 $0 $1 ... $n$[0]$[1] ... $[n]的简写。例如,使用 $0 返回当前函数或页面的第一个参数。

特殊变量this

this变量使您可以访问当前对象绑定,您可以在其中访问当前范围的所有局部变量。

因此以下变量访问是等效的:

{{
a = 5
a # output 5
this.a = 6
a # output 6
this["a"] = 7
a # output 7
}}
567

with 语句的情况下, this 运算符引用传递给 with 的对象:

{{
a = {x: 1, y: 2}
with a
b = this
end
b.x
}}
1

特殊变量empty

empty变量代表一个空对象,主要用于与 Liquid 模板兼容。它提供了一种将对象与空变量进行比较以确定它是否为空的方法:

{{
a = {}
b = [1, 2]~}}
{{a == empty}}
{{b == empty}}
true
false

对象

Scriban 支持类似 javascript 的对象 {...}

对象可以初始化为空:

{{ myobject = {} }}

一个对象可以用一些成员来初始化:

{{ myobject = { member1: "yes", member2: "no" } }}

或使用 json 语法:

{{ myobject = { "member1": "yes", "member2": "no" } }}

也可以通过多行初始化一个对象:

{{
myobject = {
member1: "yes",
member2: "no"
}
}}

可以使用点符号或方括号符号来访问对象的成员:

{{ myobject.member1 }} 等同于 {{ myobject["member1"] }}

您可以通过可选成员运算符 ? 访问链中的可选成员(而不是常规成员运算符.

{{ myobject.member1?.submember1?.submember2 ?? "nothing" }} 将返回"nothing"因为member1不包含submember1/submember2

如果该对象是纯Scriban对象(使用 {...}创建或由运行时实例化为 ScriptObject),您还可以通过简单的赋值向其添加成员:

{{
myobject = {}
myobject.member3 = "may be"
myobject.member3
}}
may be

特殊属性empty?

任何对象、数组都可以使用属性.empty?检查它是否为空:

{{
a = {}
b = [1, 2]~}}
{{a.empty?}}
{{b.empty?}}
true
false

数组

数组可以初始化为空:

{{ myarray = [] }}

可以使用一些数据项来初始化数组:

{{ myarray = [1, 2, 3, 4] }}

也可以通过多行初始化一个数组:

{{
myarray = [
1,
2,
3,
4,
]
}}

数组的项可以通过索引访问(从0开始):

{{ myarray[0] }}

如果数组是纯Scriban数组(使用 [...] 创建或由运行时实例化为 ScriptArray),您还可以通过简单的赋值向其中添加数组项,该赋值将根据索引自动扩展数组 :

{{
myarray = []
myarray[0] = 1
myarray[1] = 2
myarray[2] = 3
myarray[3] = 4
}}

您还可以使用数组内置对象来操作数组。

注意

虽然在 Scriban 中解析时空格字符大多不相关,但在某些情况下空格有助于消除数组索引器和数组初始值设定项之间的歧义。

例如,如果在 [ 之前发现空格,并且前面的表达式是变量路径表达式(见下文),则以下表达式 [...] 将被视为数组初始值设定项而不是数组索引器:

{{
myfunction [1] # myfunction 后面有一个空格。
# 它将导致调用 myfunction 并将数组作为参数传递 myvariable[1] # 没有空格,这是访问
# 访问myvariable数组元素
}}

具有属性的数组

数组还可以包含附加属性:

{{
a = [5, 6, 7]
a.x = "yes"
a.x + a[0]
}}
yes5

特殊属性size

数组有一个 size 属性,可用于查询数组中元素的数量:

{{
a = [1, 2, 3]
a.size
}}
3

函数

Scriban 允许定义四种不同类型的函数

  • 简单函数
  • 带参数的函数
  • 匿名函数
  • 内联函数

简单函数

下面声明了一个函数 sub,它接受两个参数 ab,并从 a 中减去 b 的值:

{{func sub
ret $0 - $1
end}}

所有参数都传递给特殊变量 $ ,该变量将包含直接参数列表和命名参数:

  • $0$[0] 将访问第1个参数
  • $1$[1] 将访问第2个参数
  • $[-1] 将访问最后1个参数
  • $.named将访问命名参数named

然后可以使用该函数:

{{sub 5 1}}
{{5 | sub 1}}
4
4

从上面的示例中可以注意到,使用管道(|)时,管道的结果被传递给为管道接收者的第一个参数。

请注意,函数也可以混合代码与文本编写:

{{func inc}}
这是带有以下参数的文本 {{ $0 + 1 }}
{{end}}

注意

在简单函数中设置变量(例如 a = 10)将导致在全局级别定义它,而不是在函数级别。

带参数的函数通过在函数内引入新的变量范围来解决此行为。

带参数的函数

它类似于简单函数,但它们是用括号声明的,同时还支持声明不同类型的参数(普通、可选、变量)。

简单函数的另一个区别是它们需要函数调用和参数来匹配预期的函数参数。

一个标准的带参数函数

{{func sub(x,y)
ret x - y
end}}
{{sub 5 1}}
{{5 | sub 1}}
4
4

具有普通参数和具有默认值的可选参数的函数:

{{func sub_opt(x, y, z = 1, w = 2)
ret x - y - z - w
end}}
{{sub_opt 5 1}}
{{5 | sub_opt 1}}
1
1

这里我们覆盖 z的值并将其设置为 0 而不是默认的 1:

{{sub_opt 5 1 0 }}
{{5 | sub_opt 1 0}}
2
2

具有普通参数和具有默认值的可选参数的函数:

{{func sub_variable(x, y...)
ret x - (y[0] ?? 0) - (y[1] ?? 0)
end}}
{{sub_variable 5 1 -1}
{{5 | sub_variable 1 -1}}
5
5

注意:特殊变量 $ 仍然可以在参数函数中访问,并表示参数的直接列表。 在上面的例子中 $ = [5, [1, -1]]

匿名函数

匿名函数类似于简单函数,但可以在表达式中使用(例如作为函数调用的最后一个参数)

{{ sub = do; ret $0 - $1; end; 1 | sub 3 }}
-2

它可以非常方便地构建自定义块函数:

{{ func launch; ret $0 1 2; end
launch do
ret $0 + $1
end
}}
3

内联函数

对于简单函数,像数学函数一样定义简单函数是很方便的:

{{ sub(x,y) = x - y }}

内联函数与参数函数类似,但它们只支持普通参数。 它们不支持可选或可变参数。

函数指针

因为函数也是对象,所以可以使用别名@运算符将它们存储到对象的属性中:

{{
myobject.myinc = @inc # 使用 @ 别名运算符允许引用函数而不执行它
x = 1 | myobject.myinc # x = x + 1
}}

函数别名运算符 @ 允许将一个函数作为参数传递给另一个函数,从而实现强大的函数组合。

函数调用

可以通过传递由空格分隔的参数来调用函数,例如:

{{ myfunction arg1 "arg2" (1+5) }}

管道操作符 | 还可以用于将表达式的结果通过管道传递给函数的第1个参数,例如:

{{ date.parse '2016/01/05' | date.to_string '%g' }} 将输出:06 Jan 2016

请注意,当函数接收管道调用的结果(例如上例中的 date.to_string )时,它会作为调用的第一个参数传递。

管道对于空白字符是非常贪婪的。 这允许它们跨多行链接:

{{-
"text" |
string.append "END" |
string.prepend "START"
-}}
STARTtextEND

指定参数名调用

调用时还可以指定参数名,这对于可选参数非常有用

{{func sub_opt(x, y, z = 1, w = 2)
ret x - y - z - w
end}}
{{ sub_opt 5 1 w: 3 }}
{{ 5 | sub_opt 1 w: 3 }}
0
0

请注意,一旦命名了参数,后面的参数就必须全部命名。

在使用 func 声明的自定义函数中,命名参数可以通过变量参数变量 $ 访问,但作为属性(而不是作为默认数组参数的一部分):

{{
func my_processor
"Argument count:" + $.count
"Argument options:" + $["options"]
for $x in $
"arg[" + $x + "]: " + $x
end
end my_processor "Hello" "World" count: 15 options: "optimized"
}}
Argument count: 15
Argument options: optimized
arg[0]: Hello
arg[1]: World

语句

每个语句必须由代码块 }} 或代码块中的 EOL(End Of Line) 终止,或者用分号来分隔代码块中单行上的多个语句。

表达式

Scriban 支持传统的一元和二元表达式。

变量路径表达式

变量路径表达式包含变量的路径:

  • 简单的变量访问:{{ name }}表示访问顶级变量name
  • 数组访问:{{ myarray[1] }}表示访问顶级数组变量的第1个元素
  • 成员访问: {{ myobject.member1.myarray[2] }} 表示访问顶级对象myobject的member1属性下的myarray属性的第3个数组元素

请注意,变量路径可以访问简单变量,也可以当做无参数函数调用。

赋值表达式

可以将值分配给顶级变量或对象/数组的成员:

  • {{ name = "foo" }} 表示将字符串"foo"赋值给了name变量
  • {{ myobject.member1.myarray[0] = "foo" }}

赋值表达式必须是顶级表达式语句,并且不能在子表达式中使用

嵌套表达式

() 括起来的表达式表示嵌套表达式,例如:

{{ name = ('foo' + 'bar') }}

算术表达式

数字支持以下二元运算符:

操作 描述
<left> + <right> 2个数字相加,例如:1 + 2
<left> - <right> 左边数字减右边,例如:2 - 1
<left> * <right> 2个数字相乘,例如:2 * 2
<left> / <right> 左边除以右边,例如:2 / 1
<left> // <right> 左边除以右边并四舍五入为整数
<left> % <right> 左边除以右边取余数

如果 leftright 是浮点数,而另一个是整数,则运算结果将为浮点数。

字符串表达式

字符串支持以下二元运算符:

操作 描述
'left' + <right> 拼接2个字符串,例如:"ab" + "c"结果为"abc"
'left' * <right> 将左边的字符串重复right次,例如:'a' * 5结果为aaaaa
字符串与数字的左右顺序是可以交换的,例如:5 * 'a'

二元运算中只要有一个字符串,其他部分就会自动转换为字符串。

以下代码将转换为字符串:

  • null -> ""例如:"aaaa" + null -> "aaaa"
  • 0 -> "0"
  • 1.0 -> "1.0"
  • true -> "true"
  • false -> "false"

条件表达式

布尔表达式通过比较左右值来生成布尔值。

操作 描述
<left> == <right> 左右是否相等?
<left> != <right> 左右是否不等?
<left> > <right> 左边是否大于右边?
<left> >= <right> 左边是否大于等于右边?
<left> < <right> 左边是否小于右边?
<left> <= <right> 左边是否小于等于右边?

以上表达式支持数字、字符串、日期时间

您可以将条件表达式与 &&(与运算符)||(或运算符)结合起来用。

与 javascript 不同,它总是返回布尔值,并且从不返回 或

操作 描述
<left> && <right> 左边为真 并且 右边为真
<left> || <right> 左边为真 或者 右边为真

三元条件表达式

同时支持Javascript一样的三元表达式:条件 ? 条件为真时的取值 : 条件为假时的取值

{{
gender = name == "frank" ? "男" : "女"
gender
}}

一元表达式

操作 描述
! <expression> 布尔值取反。例如:if !page
+ <expression> 算数正数表达式。例如:+1.5
- <expression> 算数负数表达式
^ <expression> 展开传递给函数调用参数的数组(请参阅函数调用)
@ <expression> 如果是函数调用则将计算的表达式结果的函数指针
++ <variable> 变量自增,与Javascript中的等效
-- <variable> 变量自减,与Javascript中的等效
<variable> ++ 变量自减,与Javascript中的等效
<variable> -- 变量自减,与Javascript中的等效

注意:对于自增和自减运算符,操作数必须是变量、属性或索引器

范围表达式

它们是提供迭代器的特殊二进制表达式(通常与 for 语句一起使用)。

其中 leftright表达式必须在运行时解析为整数。

操作 描述
left..right 返回一个迭代器,内容范围为leftright
步长为1,结果内容包含 right
例如:1..5返回的是[1, 2, 3, 4, 5]
left..<right 返回一个迭代器,内容范围为leftright
步长为1,结果内容不包含 right
例如:1..<5返回的是[1, 2, 3, 4]

null合并运算符:??, ?!

# 常规写法
name2 = name != null ? name : "未知" # 优雅写法
name2 = name ?? "未知"
# 常规写法
name2 = name == null ? name : "未知" # 优雅写法
name2 = name ?! "未知"

if <表达式>, else, else if <表达式>

一般语法是:

{{
if <表达式>
...
else if <表达式>
...
else
...
end
}}

if 语句必须以 end 结束,或者后跟 elseelse if 语句。

elseelse if 语句后面必须跟有 elseelse if 或以 end语句结束。

对于 ifelse if后面的表达式,其计算结果必需为布尔值。

真与假

默认情况下,当计算为布尔值时,只有 nullfalse 被视为 false

当用于if判断时,以下值也可以隐式转换为布尔值:

  • 0 -> true
  • 1 -> true 或任意非0的值
  • **null -> false**
  • **false -> false**
  • 非null的对象 -> true
  • "" -> true 空字符串返回true
  • "foo" -> true

casewhen

这相当于 C# 中的 switch 语句,这是一个选择语句,它根据值匹配从候选列表中选择要执行的单个 switch 部分。

  • case <expression>要判断的变量或表达式
  • when <match>允许与指定表达式和case表达式匹配
    • when 也可以与用,||分隔的多个值一起使用
  • 最后的 else 可以用作默认处理情况,以防没有匹配的情况。
{{
x = 5
case x
when 1, 2, 3
"Value is 1 or 2 or 3"
when 5
"Value is 5"
else
"Value is " + x
end
}}
Value is 5

循环

for <variable> in <expression> ... end

{{for <variable> in <expression>}}
...
{{end}}

表达式可以是数组或范围迭代器:

  • 在数组上循环: {{ for page in pages }} 这是页面 {{ page.title }}{{ end }}
  • 在迭代器上循环: {{ for x in 1..n }} 这是循环体 [{{x}}]{{ end }}

for 循环(以及下面的 tablerow 语句)支持附加参数offset, limitreversed ,它们也可以一起使用:

offset参数

允许在指定的从零开始的索引处开始循环迭代:

{{~ for $i in (4..9) offset:2 ~}}
{{ $i }}
{{~ end ~}}
6
7
8
9
limit参数

限制迭代次数

{{~ for $i in (4..9) limit:2 ~}}
{{ $i }}
{{~ end ~}}
4
5
reversed参数

倒序迭代

{{~ for $i in (1..3) reversed ~}}
{{ $i }}
{{~ end ~}}
3
2
1
特殊循环变量

以下变量可在 for 块中访问:

名称 描述
{{for.index}} The current index
of the for loop
{{for.rindex}} The current index
of the for loop starting from the end of the list
{{for.first}} A boolean indicating whether this is the first step in the loop
{{for.last}} A boolean indicating whether this is the last step in the loop
{{for.even}} A boolean indicating whether this is an even row in the loop
{{for.odd}} A boolean indicating whether this is an odd row in the loop
{{for.changed}} A boolean indicating whether a current value of this iteration changed from previous step

while <expression> ... end

{{while <expression>}}
...
{{end}}

当表达式结果为true时则循环

特殊循环变量

以下变量可在 while 块中访问:

名称 描述
{{while.index}} The current index
of the while loop
{{while.first}} A boolean indicating whether this is the first step in the loop
{{while.even}} A boolean indicating whether this is an even row in the loop
{{while.odd}} A boolean indicating whether this is an odd row in the loop

tablerow <variable> in <expression> ... end

此函数生成与 HTML 表兼容的 HTML 行。 必须包含在开始

和结束

HTML 标记中。

This statement is mainly for compatibility reason with the liquid tablerow tag.

It uses similar syntax to a for statement (supporting the same parameters).

{{tablerow <variable> in <expression>}}
...
{{end}}
<table>
{{~ tablerow $p in products | array.sort "title" -}}
{{ $p.title -}}
{{ end ~}}
</table>
<table>
<tr class="row1"><td class="col1">Apple</td></tr>
<tr class="row2"><td class="col1">Banana</td></tr>
<tr class="row3"><td class="col1">Computer</td></tr>
<tr class="row4"><td class="col1">Mobile Phone</td></tr>
<tr class="row5"><td class="col1">Orange</td></tr>
<tr class="row6"><td class="col1">Sofa</td></tr>
<tr class="row7"><td class="col1">Table</td></tr>
</table>
The cols parameter

Defines the number of columns to output:

<table>
{{~ tablerow $p in (products | array.sort "title") limit: 4 cols: 2 -}}
{{ $p.title -}}
{{ end ~}}
</table>
<table>
<tr class="row1"><td class="col1">Apple</td><td class="col2">Banana</td></tr>
<tr class="row2"><td class="col1">Computer</td><td class="col2">Mobile Phone</td></tr>
</table>

breakcontinue

break 语句允许提前退出循环

{{ for i in 1..5
if i > 2
break
end
end }}

continue 语句允许跳过循环的其余部分并继续下一步

{{ for i in 1..5
if i == 2
continue
end
}}
[{{i}}]] step
{{ end }}
[1] step
[3] step
[4] step
[5] step

capture <variable> ... end

capture <variable> ... end 语句允许将模板输出捕获到变量:

例如下面的代码:

{{ capture myvariable }}
This is the result of a capture {{ date.now }}
{{ end }}

将设置myvariable = "This is the result of a capture 06 Jan 2016\n"

readonly <variable>

readonly 语句阻止变量进行后续赋值:

{{ x = 1 }}
{{ readonly x }}
{{ x = 2 }} <- 这将导致运行时错误

import <variable_path>

import <variable_path> 语句允许将对象的成员作为当前绑定的变量导入:

{{
myobject = { member1: "yes" }
import myobject
member1 # 将打印“yes”字符串到输出
}}

请注意,只读变量不会被覆盖。

with <variable> ... end

The with <variable> ... end statement will open a new object context with the passed variable, all assignment will result in setting the members of the passed object.

myobject = {}
with myobject
member1 = "yes"
end

wrap <function> <arg1...argn> ... end

将语句块传递给函数,该函数将能够使用特殊变量 $$ 对其进行计算

{{
func wrapped
for $i in 1..<$0
$$ # 这个特殊变量计算传递给包装语句的块
end
end wrap wrapped 5
$i + " -> This is inside the wrap!\r\n"
end
}}
1 -> This is inside the wrap!
2 -> This is inside the wrap!
3 -> This is inside the wrap!
4 -> This is inside the wrap!

请注意,在 with 块外部声明的变量可以在内部访问。

include <name> arg1?...argn?

include is not a statement but rather a function that allows you to parse and render a specified template. To use this function, a delegate to a template loader must be setup on the [TemplateOptions.TemplateLoader](runtime.md#include-and-itemplateloader) property passed to the Template.Parse method.

include 'myinclude.html'
x = include 'myinclude.html'
x + " modified"

assuming that myinclude.html is

{{ y = y + 1 ~}}
This is a string with the value {{ y }}

will output:

This is a string with the value 1
This is a string with the value 2 modified

ret <expression>?

ret语句用于提前退出顶级/包含页面或函数。

This is a text
{{~ ret ~}}
This text will not appear
This is a text

Scriban语言手册中文版的更多相关文章

  1. Spring4参考手册中文版

    Spring4参考手册中文版 前言 https://github.com/b2gats/stone-docs/blob/master/spring-4-beans.md Part III. 核心技术 ...

  2. 转:Egret社区翻译的《TypeScript语言手册》

      <TyptScript语言手册>第1章-介绍<TypeScript语言手册>第2章-基本概念<TypeScript语言手册>第3章-类型<TypeScri ...

  3. Java日志框架-Logback手册中文版以及官方配置文档教程

    Logback手册中文版:(链接: https://pan.baidu.com/s/1bpMyasR 密码: 6u5c),虽然版本有点旧,但是大体意思差不多,先用中文版了解个大概,然后一切最新的配置以 ...

  4. man手册中文版实现

    1.添加库函数手册 sudo apt-get install manpages-dev 2.让man显示中文 ubuntu源里面已经包含了中文的man包,所以不用从其他地方down了,直接sudo a ...

  5. Linux-查看C语言手册及man的特殊用法

    man命令可以查看c语言库函数的函数原型, 比如 $ man malloc 如果显示 "No manual entry for malloc", 则需要安装 "man-p ...

  6. Go语言圣经[中文版]

    近期整理了一篇Go语言圣经[中文版]在线版本,排版比较适合手机以及PC阅读. Go语言圣经[中文版本]

  7. 视频直播点播nginx-rtmp开发手册中文版

    2016年8月18日12:42:35 参照官方文档https://github.com/arut/nginx-rtmp-module/wiki/Directives 请注意这个是粗翻译版,仅供参考,不 ...

  8. Pandas速查手册中文版

    本文翻译自文章: Pandas Cheat Sheet - Python for Data Science ,同时添加了部分注解. 对于数据科学家,无论是数据分析还是数据挖掘来说,Pandas是一个非 ...

  9. MPlayer 使用手册中文版

    播放文件 使用 MPlayer 播放媒体文件最简单的方式是: mplayer <somefile> MPlayer 会自动检测文件的类型并加以播放,如果是音频文件,则会在命令行中显示该播放 ...

  10. R语言手册

    在R的官方教程里是这么给R下注解的:一个数据分析和图形显示的程序设计环境(A system for data analysis and visualization which is built bas ...

随机推荐

  1. 探索 GO 项目依赖包管理与Go Module常规操作

    探索 GO 项目依赖包管理与Go Module常规操作 目录 探索 GO 项目依赖包管理与Go Module常规操作 一.Go 构建模式的演变 1.1 GOPATH (初版) 1.1.1 go get ...

  2. Sqlite管理工具

    ! https://zhuanlan.zhihu.com/p/375188242 SQLiteStudio 开源免费的一款sqlite数据库管理软件,支持windows,linux,macos 官网: ...

  3. TienChin 渠道管理-表创建

    在若依当中,有个槽点,就是数据库当中的删除标识状态一般 0 是 false,1 是 true,在若依当中反而 0 是 true,1 是 false. 渠道表设计,我这里就直接贴成品的创建表 SQL: ...

  4. 利用Mybatis拦截器实现自定义的ID自增器

    原生的Mybatis框架是没有ID自增器,但例如国产的Mybatis Plus却是支持,不过,Mybatis Plus却是缺少了自定属性的填充:例如:我们需要自定义填充一些属性,updateDate. ...

  5. 8.10 TLS线程局部存储反调试

    TLS(Thread Local Storage)用来在进程内部每个线程中存储私有的数据.每个线程都会拥有独立的TLS存储空间,可以在TLS存储空间中保存线程的上下文信息.变量.函数指针等.TLS其目 ...

  6. 解决.netWebAPI输出时间格式带T问题

    GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings.Converters.Add( new Ne ...

  7. 【C++深度剖析】为什么C++支持函数重载而C不支持--C++程序编译链接过程--符号表生成规则【Linux环境超详细解释C++函数重载底层原理】

    文章目录 前言 Linux环境g++编译器的配置以及一些准备工作 源文件的符号表生成以及分析 尾声 前言 先赞后看好习惯 打字不容易,这都是很用心做的,希望得到支持你 大家的点赞和支持对于我来说是一种 ...

  8. Android 子线程更新UI的六种方式

    1.注意: (1)子线程需要切换到UI线程或者主线程去更新线程. (2)但是子线程单独也是可以更新UI的,只是谷歌要求我们需要到UI线程去更新. eg: @Override protected voi ...

  9. DNS转发器·

    实验介绍:dns转发器的作用 当客户端向dns1询问域名对应IP时,如果dns1不是该区域的授权域名服务器,则无法解析域名 dns1会根据转发器转发给dns3,如果dns3能解析,则返回给dns1. ...

  10. Hadoop相关面试题

    1.简答说一下hadoop的map-reduce编程模型 首先map task会从本地文件系统读取数据,转换成key-value形式的键值对集合 使用的是hadoop内置的数据类型,比如longwri ...