跳转至

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 := template_render("hello {{name}}!", array("name":"world"))
变量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}}

给定以下数据:

{
  "name": "Chris",
  "value": 10000,
  "taxed_value": 10000 - (10000 * 0.4),
  "in_ca": true
}

会产生以下内容:

Hello Chris
You have just won 10000 dollars!
Well, 6000.0 dollars, after taxes.

描述

Mustache 可用于 HTML、配置文件、源代码 - 任何东西。它通过使用散列或对象中提供的值扩展模板中的标签来工作。

我们称其为“无逻辑”,因为没有 if 语句、else 子句或 for 循环。相反,只有标签。一些标签被替换为一个值,一些什么都没有,还有一些是一系列值。本文档解释了不同类型的 Mustache 标签。

标签类型

标签由{{}}表示。{{person}}是一个标签,就像{{#person}}. 在这两个示例中,我们都将其称为person键或标签键。让我们谈谈不同类型的标签。

变量

最基本的标记类型是变量。基本模板中的标签将尝试在当前上下文中{{name}}查找键。name如果没有name键,将递归检查父上下文。如果到达顶部上下文但name仍未找到,则不会呈现任何内容。

默认情况下,所有变量都是 HTML 转义的。如果要返回未转义的 HTML,请使用三重胡须:{{{name}}}

您还可以使用&unescape 变量:{{& name}}. 这在更改分隔符时可能很有用(请参阅下面的“设置分隔符”)。

默认情况下,变量“miss”返回一个空字符串。

模板:

* {{name}}
* {{age}}
* {{company}}
* {{{company}}}

数据:

{
  "name": "Chris",
  "company": "<b>GitHub</b>"
}

输出:

* Chris
*
* &lt;b&gt;GitHub&lt;/b&gt;
* <b>GitHub</b>

区块(Sections)

区块呈现文本块一次或多次,具体取决于当前上下文中的键值。

一个区块以井号开始,以斜线结束。也就是说,{{#person}}开始一个person区块,同时{{/person}}结束它。

该部分的行为由键的值决定。

错误值或空列表

如果该person键存在且值为 false 或空列表,则不会显示井号和斜线之间的 HTML。

模板:

Shown.
{{#person}}
  Never shown!
{{/person}}

数据:

{
  "person": false
}

输出:

Shown.

非空列表

如果该person键存在并且具有非假值,井号和斜杠之间的 HTML 将被呈现并显示一次或多次。

当值为非空列表时,块中的文本将为列表中的每个项目显示一次。块的上下文将被设置为每次迭代的当前项目。这样我们就可以遍历集合。

模板:

{{#repo}}
  <b>{{name}}</b>
{{/repo}}

数据:

{
  "repo": [
    { "name": "resque" },
    { "name": "hub" },
    { "name": "rip" }
  ]
}

输出:

<b>resque</b>
<b>hub</b>
<b>rip</b>

lambda

当该值是可调用对象(例如函数或 lambda)时,将调用该对象并传递文本块。传递的文本是文字块,未呈现。{{tags}}不会被扩展 - lambda 应该自己做。通过这种方式,您可以实现过滤器或缓存。

模板:

{{#wrapped}}
  {{name}} is awesome.
{{/wrapped}}

数据:

{
  "name": "Willy",
  "wrapped": function() {
    return function(text, render) {
      return "<b>" + render(text) + "</b>"
    }
  }
}

输出:

<b>Willy is awesome.</b>

非错误值

当值为非 false 但不是列表时,它将用作块的单个渲染的上下文。

模板:

{{#person?}}
  Hi {{name}}!
{{/person?}}

数据:

{
  "person?": { "name": "Jon" }
}

输出:

Hi Jon!

倒置区块(Inverted Sections)

倒置部分以插入符号(帽子)开始,以斜杠结束。那是{{^person}}开始一个person的倒置部分,而{{/person}}结束它。

虽然部分可用于根据键值呈现文本一次或多次,但反转部分可根据键的反向值呈现文本一次。也就是说,如果键不存在、为假或为空列表,它们将被渲染。

模板:

{{#repo}}
  <b>{{name}}</b>
{{/repo}}
{{^repo}}
  No repos :(
{{/repo}}

数据:

{
  "repo": []
}

输出:

No repos :(

注释

注释以!开始并被忽略。以下模板:

<h1>Today{{! ignore me }}.</h1>

将呈现如下:

<h1>Today.</h1>

评论可能包含换行符。

代码片段(Partials)

代码片段以大于号开头,例如{{> box}}.

部分在运行时呈现(与编译时相反),因此递归部分是可能的。只是避免无限循环。

{{> next_more}}

通过这种方式,您可能希望将部分视为包含、导入、模板扩展、嵌套模板或子模板,即使这些在此处并非字面意思。

例如,这个模板和部分:

base.mustache:
<h2>Names</h2>
{{#names}}
  {{> user}}
{{/names}}

user.mustache:
<strong>{{name}}</strong>

可以被认为是一个单一的、扩展的模板:

<h2>Names</h2>
{{#names}}
  <strong>{{name}}</strong>
{{/names}}

设置分隔符

设置定界符标记以等号开头,并将标记定界符从{{自定义字符串更改}}为自定义字符串。

考虑以下人为的示例:

* {{default_tags}}
{{=<% %>=}}
* <% erb_style_tags %>
<%={{ }}=%>
* {{ default_tags_again }}

这里我们有一个包含三个项目的列表。第一项使用默认标记样式,第二项使用 Set Delimiter 标记定义的 erb 样式,第三项在另一个 Set Delimiter 声明后返回默认样式。 自定义分隔符不能包含空格或等号。