5 个版本 (3 个重大更新)

0.5.0 2021年1月18日
0.4.2 2020年11月17日
0.4.0 2020年7月26日
0.3.0 2020年7月21日
0.1.0 2019年9月16日

模板引擎 中排名第 209

Download history 23/week @ 2024-03-11 1/week @ 2024-03-18 37/week @ 2024-04-01 5/week @ 2024-04-22 1/week @ 2024-05-27

每月下载量 59
2 crates 中使用

MIT/Apache 许可

110KB
2.5K SLoC

Templar

Continuous Build GitHub release Crate Book API Docs Crates.io

Templar 是一个 Rust 库,也是一个用于处理模板的 CLI 工具。其用法和风格受到了 Jinja2 和 Ansible 的启发,尽管它并不是这两个的复制品。

该项目目标是提供快速且灵活的动态模板功能,特别适用于配置和本地工具。尽管如此,它也可能适用于 HTML 和前端渲染。

示例

考虑到它所基于的框架,模板语法可能很熟悉。例如,一个简单的模板可能看起来像这样

user_name={{ user.name }} {# Replace with the context property 'name' in 'user' #}
full_context={{ . | json("pretty") }} {# Dump the entire context as JSON, '.' is the root node #}
password={{ script('echo hunter2 | md5sum') }} {# Execute a shell command and calculate the MD5 sum #}

除了简单的替换之外,还可以使用更复杂的表达式。

The calculated result is {{ 100 * 5 / 10 }} {#- Prints '50' #}

Today's guest list:
{%- for person in ['Bob', 'Joe', 'Jen', 'Amy')] %}
* {{ person }} will come to the party!
{%- endfor %} {#- This will loop everyone in the inline array above, but they array could also come from the context #}

另一个模板框架?

嗯...是的。

现在有许多优秀的模板框架,但它们大多数都是为网络或 HTML 渲染设计的。这导致当用于其他目的时存在一些缺点。

  • Templar 对解析配置文件提供了第一级支持。您可以直接从使用 serde 解析的配置中创建上下文,或者也可以用于模板化 serde 子元素。
  • 您可以选择直接解析表达式而不是整个模板。
  • 上下文值在访问时才会被懒加载处理。
  • 上下文值可以引用其他上下文值。
  • 扩展基本功能很简单。
  • 支持在每次访问时重新计算的动态上下文节点。例如,重复调用具有此内容的模板 {% if user.isRoot %} {{ do_something() }} {% end if %} 如果 user.isRoot 的值发生变化,则会发生变化。

模板语法

大部分语法基于出色的 Jinja2 项目。以下是一些目前支持的功能。

  • 可以使用 {{ }} 语法进行值替换。
    • 支持的文字包括字符串(单引号、双引号或反引号引用)、布尔值、数字(目前解析为 i64)、null、数组、和映射
    • 以字母字符开头的标识符可以直接引用,例如 {{ some.value.path }}
    • 可以使用 . 来引用根节点,允许使用如 {{ . | json }} 来将整个上下文作为 JSON 输出
    • 可以使用括号语法引用非标准类型的标识符,例如以非字母字符开头、空格等。例如 {{ .['565'] }}。这还允许访问数组和非标准类型的标识符(例如布尔值)。
    • 内联数组: {{ [1,2,3,4] }},复杂的嵌套也可行,例如 {{ [1,2, script("echo 'hello world!'"), (5 + 5 | base64)] }}
    • 内联地图:{{ {'key': 'value', 'otherKey': { 'nested': 'map' } } }}
  • 可以使用{% %}语法来进行控制流程
    • if/else if:{% if 10/2 == 5 %}世界是理智的!}我们在什么宇宙里?}% end if %}
    • 作用域可以手动设置:{% scope %}I'm 在一个作用域中!}% end scope %}
    • for循环:{% for thing in lots.of.stuff %} {{ thing['name'] }} }% end for %}。for循环总是进入新的作用域。
  • 注释使用{# #}语法,并且将从输出中省略。
  • 可以通过向上述任何块中添加一个-来完成空白控制,例如:{{- 'no whitespace! -}}
    • 空白控制可以添加到标签的一侧或两侧。所有带有-的侧面的空格、新行或其他空白都将被移除,就像块紧邻其他元素一样。

由于文档仍在进行中,请参阅厨房水槽以了解模板使用的示例。

表达式语法

标准 {{ }} 块内的所有内容都是一个表达式。每个块恰好包含一个表达式,但这个表达式可以通过许多单独的操作进行链式调用。简要概述

  • 数学运算:+ - * / % 这些运算仅适用于数值类型
  • 相等性:== != < <= > >= && ||
  • 值设置:= 此操作的左侧必须是某个标识符,例如 {{ some.val.path = 'hello world!' }}
  • 字符串连接:~ 例如 {{ 'Hello' ~ ' ' ~ 'world!' }} 打印 "Hello world!"
  • 函数:ident() 例如 {{ env('USER') }} 会检索环境变量 "USER" 的值。
  • 过滤器:| 例如 {{ 'hello world' | upper }} 会使用 'upper' 过滤器打印 "HELLO WORLD"

由于文档仍在进行中,请参阅 表达式测试 以了解表达式用法的示例。

性能

Templar 优先考虑渲染性能而不是解析性能。虽然你应该带着一些怀疑来对待大多数基准测试,但简单的模板渲染只需要几微秒。在我的 AMD Ryzen 2700U 处理器上,我可以在单个线程上每秒渲染约 300,000 次简单的模板。

模板种类繁多,调用 shell 命令或执行其他复杂任务的模板将获得较慢的性能。

API

完整的 API 文档可以在 docs.rs 上找到

依赖

~2.6–4.5MB
~87K SLoC