tmpl_plugin
TSL语言的跨平台实现的模板插件。模板语法基于{{ mustache }}。
安装
(已集成到mytsl
发行版中)
动态库文件:Windows: tmpl_plugin.dll 或者 Linux: libtmpl_plugin.so。
把相关的动态库文件拷贝到执行服务器或者TSL目录的plugin目录。
(如果需要下载兼容正式版的Windows版本的动态库文件请访问这里)。
使用指南
提供的TSL函数:
template_render
template_render(tmpl, data, [context], [options])
: 模板渲染。
-
参数列表
参数 描述 tmpl 模板,字符串类型。 data 数据变量。 context 上下文,例如可以包含模板代码片段以便重用。array类型。 options 配置属性,struct类型。可以配置escape等等。 -
返回值
字符串。
-
例子
简单的例子:
变量s等于hello world!
。
复杂一点的例子:
data := array(
("url":"/stk/SZ000002","StockID":"SZ000002","StockName":"万 科A","date":44218.5925925926,"price":29.15,"open":29.15,"close":29.15,"high":29.15,"low":29.15,"vol":0.0,"amount":0.0),
("url":"/stk/SZ000002","StockID":"SZ000002","StockName":"万 科A","date":44218.5926041667,"price":29.14,"open":29.14,"close":29.14,"high":29.14,"low":29.14,"vol":11400.0,"amount":332181.0));
tpl := "
{{#items}}
<li><a {{>href}}>{{StockID}}|{{StockName}}|{{date:T}}|{{price}}|{{open}}|{{high}}|{{low}}|{{close}}|{{vol}}|{{amount}}</a></li>
{{/items}}
";
s := template_render(tpl
, array("items": data) // 数据
, array("href": "href=\"{{url}}\"") // 定义href如何渲染
, $[escape:"html"] // 按html格式做escape
);
<li><a href="/stk/SZ000002">SZ000002|万 科A|2021-01-22 14:13:20|29.15|29.15|29.15|29.15|29.15|0|0</a></li>
<li><a href="/stk/SZ000002">SZ000002|万 科A|2021-01-22 14:13:21|29.14|29.14|29.14|29.14|29.14|11400|332181</a></li>
"date"
字段从浮点数转成了日期时间,这是{{date:T}}
的功劳。可以在{{}}
中使用fmt插件的相关格式类型,相当的方便。
template_render_file
template_render_file(file, data, [context], [options])
: 渲染模板文件。
-
参数列表
参数 描述 file 模板文件名,字符串类型。 data 数据变量。 context 上下文,例如可以包含模板代码片段以便重用。array类型。 options 配置属性,struct类型。可以配置escape等等。 -
返回值
字符串。
-
例子
模板文件 test.tmpl:
hello {{name}} from file!
调用 template_render_file("test.tmpl", array("name":"world"))
返回:
hello world from file!
template_write_file
template_write_file(file, data, output, [context], [options])
: 渲染模板文件并输出到文件中。
-
参数列表
参数 描述 file 模板文件名,字符串类型。 data 数据变量。 output 输出模板文件名。 context 上下文,例如可以包含模板代码片段以便重用。array类型。 options 配置属性,struct类型。可以配置escape等等。 -
返回值
1 成功 0 失败。
模板说明
mustache的模板语法支持
参见 {{ mustache }},spec定义。
支持的特性
- 变量(Variables)
- 区块(Sections)
- 倒置区块(Inverted Sections)
- 注释(Comments)
- 代码片段(Partials)
- Lambdas
- 设置分隔符(Set Delimiter)
- HTML转义 (可配置)
- Inheritance (extension)
- Dynamic Names (extension)
扩展
- 支持fmt的格式化类型,例如
{{var:T}}
。 - map扩展区块, 例如
{{*map}}({{key}} -> {{value}}){{/map}}
. - 过滤区块, 例如
{{?filter}}...{{/filter}}
.
Lambdas例子
模板变量可以是匿名函数,模板在渲染时将会调用该匿名函数,并会把当前的内容做为只读参数view
送入。
可以用view.new_content_list()
方法来生成新的内容列表,view.contents
返回当前的内容列表。
可以通过返回新的内容列表来改变要渲染的内容。
内容列表提供下列方法:
方法 | 参数 | 说明 |
---|---|---|
append(contents) | 内容列表 | 追加内容列表 |
append_text(text) | 文本 | 追加文本内容 |
append_var(name) | 变量名 | 追加变量 |
例子:
tpl := "{{#lambda}}ABC{{/lambda}} != {{#lambda}}XYZ{{/lambda}}";
s := template_render(tpl
, array("lambda": (view) =>
begin
c := view.new_content_list();
c.append_text("__");
c.append(view.contents);
c.append_text("__");
return c;
end)
, array());
echo s;
__ABC__ != __XYZ__
附录
以下内容摘抄自mutache的使用说明。
概要
典型的 Mustache 模板:
Hello {{name}}
You have just won {{value}} dollars!
{{#in_ca}}
Well, {{taxed_value}} dollars, after taxes.
{{/in_ca}}
给定以下数据:
会产生以下内容:
描述
Mustache 可用于 HTML、配置文件、源代码 - 任何东西。它通过使用散列或对象中提供的值扩展模板中的标签来工作。
我们称其为“无逻辑”,因为没有 if 语句、else 子句或 for 循环。相反,只有标签。一些标签被替换为一个值,一些什么都没有,还有一些是一系列值。本文档解释了不同类型的 Mustache 标签。
标签类型
标签由{{}}
表示。{{person}}
是一个标签,就像{{#person}}
. 在这两个示例中,我们都将其称为person
键或标签键。让我们谈谈不同类型的标签。
变量
最基本的标记类型是变量。基本模板中的标签将尝试在当前上下文中{{name}}
查找键。name
如果没有name
键,将递归检查父上下文。如果到达顶部上下文但name
仍未找到,则不会呈现任何内容。
默认情况下,所有变量都是 HTML 转义的。如果要返回未转义的 HTML,请使用三重胡须:{{{name}}}
。
您还可以使用&
unescape 变量:{{& name}}
. 这在更改分隔符时可能很有用(请参阅下面的“设置分隔符”)。
默认情况下,变量“miss”返回一个空字符串。
模板:
数据:
输出:
区块(Sections)
区块呈现文本块一次或多次,具体取决于当前上下文中的键值。
一个区块以井号开始,以斜线结束。也就是说,{{#person}}
开始一个person
区块,同时{{/person}}
结束它。
该部分的行为由键的值决定。
错误值或空列表
如果该person
键存在且值为 false 或空列表,则不会显示井号和斜线之间的 HTML。
模板:
数据:
输出:
非空列表
如果该person
键存在并且具有非假值,井号和斜杠之间的 HTML 将被呈现并显示一次或多次。
当值为非空列表时,块中的文本将为列表中的每个项目显示一次。块的上下文将被设置为每次迭代的当前项目。这样我们就可以遍历集合。
模板:
数据:
输出:
lambda
当该值是可调用对象(例如函数或 lambda)时,将调用该对象并传递文本块。传递的文本是文字块,未呈现。{{tags}}
不会被扩展 - lambda 应该自己做。通过这种方式,您可以实现过滤器或缓存。
模板:
数据:
{
"name": "Willy",
"wrapped": function() {
return function(text, render) {
return "<b>" + render(text) + "</b>"
}
}
}
输出:
非错误值
当值为非 false 但不是列表时,它将用作块的单个渲染的上下文。
模板:
数据:
输出:
倒置区块(Inverted Sections)
倒置部分以插入符号(帽子)开始,以斜杠结束。那是{{^person}}
开始一个person
的倒置部分,而{{/person}}
结束它。
虽然部分可用于根据键值呈现文本一次或多次,但反转部分可根据键的反向值呈现文本一次。也就是说,如果键不存在、为假或为空列表,它们将被渲染。
模板:
数据:
输出:
注释
注释以!
开始并被忽略。以下模板:
将呈现如下:
评论可能包含换行符。
代码片段(Partials)
代码片段以大于号开头,例如{{> box}}
.
部分在运行时呈现(与编译时相反),因此递归部分是可能的。只是避免无限循环。
通过这种方式,您可能希望将部分视为包含、导入、模板扩展、嵌套模板或子模板,即使这些在此处并非字面意思。
例如,这个模板和部分:
base.mustache:
<h2>Names</h2>
{{#names}}
{{> user}}
{{/names}}
user.mustache:
<strong>{{name}}</strong>
可以被认为是一个单一的、扩展的模板:
设置分隔符
设置定界符标记以等号开头,并将标记定界符从{{
自定义字符串更改}}
为自定义字符串。
考虑以下人为的示例:
这里我们有一个包含三个项目的列表。第一项使用默认标记样式,第二项使用 Set Delimiter 标记定义的 erb 样式,第三项在另一个 Set Delimiter 声明后返回默认样式。 自定义分隔符不能包含空格或等号。