16 个版本
0.4.1 | 2024 年 4 月 27 日 |
---|---|
0.3.7 | 2023 年 11 月 4 日 |
0.3.3 | 2023 年 7 月 4 日 |
0.2.0 | 2023 年 3 月 3 日 |
0.1.0 | 2022 年 12 月 11 日 |
#43 在 模板引擎
1,110 每月下载量
60KB
962 行
模板
基于 JSON、YAML 或 HCL 配置的 CLI。
灵感来源于 Consul Template、Sprig、Handlebars、Mustache 以及 Kotlin、Rust、Go 和 Python 的标准库。
安装
Cargo
使用
cargo install template-cli
预编译的二进制文件
您可以从 最新版本页面 下载适用于多种架构和操作系统的预编译二进制文件。
Docker
二进制文件以 Docker 镜像 的形式提供。
在下面的使用说明中,将所有 template
的用法替换为 docker run --rm ghcr.io/hiddewie/template
。
使用方法
template --template ./path/to/template.template --configuration ./path/to/configuration.json
使用 --help
选项显示使用信息
template --help
输出如下
CLI for templating based on JSON, YAML or HCL configuration
Usage: template [OPTIONS] --template <TEMPLATE> --configuration <CONFIGURATION>
Options:
-t, --template <TEMPLATE> Absolute or relative path to the template file
-c, --configuration <CONFIGURATION> Absolute or relative path to the configuration file. Provide `-` as path to read the configuration input from the standard input stream
-f, --format <FORMAT> Specify the format of the configuration input. Useful when the configuration file has a non-standard extension, or when the input is given in the standard input stream [possible values: json, hcl, yaml]
-h, --help Print help information
-V, --version Print version information
输出将渲染到标准输出流。日志消息将输出到标准错误流。可以通过使用 RUST_LOG
环境变量 来控制日志级别。
此工具与其他命令行工具配合良好,遵循 UNIX 哲学,例如
curl -s 'https://dummyjson.com/products' \
| jq '{ items: .products }' \
| template --configuration - --template products.template \
| head -n 5 \
> product-list.txt
退出代码
0
:成功。标准输出包含渲染的模板。1
:无法读取模板文件。2
:未给出所需的 CLI 选项之一。3
:无法读取配置文件。4
:无法解析配置文件。5
:无法解析模板文件。6
:无法渲染模板。101
:恐慌。发生了意外的错误,并且未正确处理。请创建一个问题来报告配置、模板和错误输出。
安全性
此软件
- 读取配置文件或标准输入
- 读取模板文件
- 读取环境以设置日志级别,如果使用了
environment
函数 - 不写入任何文件
- 不建立任何网络连接
配置
如果配置文件具有不同的扩展名,或者在标准输入流中提供配置时,可以使用 --format
选项配置配置格式。
模板化
有关正式模板语法的详细信息,请参阅 Pest 语法。
建议模板文件使用扩展名 .template
。
渲染配置数据
配置
{
"value": "Hello",
"nested": {
"value": "world"
}
}
使用模板
{% value %} {% nested.value %}{% does_not_exist %}!
生成输出
Hello world!
YAML 配置文件
value: Hello
nested:
value: world
或 HCL 配置文件
value = "Hello"
nested {
value = "world"
}
将生成等效的输出。
注释
注释将被忽略,内容不会作为输出渲染
This is rendered {# comment #}
{# {% for item in array %}
This is not a loop
{% end %} #}
This is rendered
文字
Null: {% null %}
Boolean: {% true %} and {% false %}
Integer: {% 0 %}, {% -0 %}, {% -100 %} and {% 100 %}
Floating point: {% .0 %}, {% 0. %}, {% -1.0 %}, {% 10.47e1 %} and {% -1.47e-10 %}
String: {% "" %} and {% "value" %}
Array: {% [] %}, {% [1] %} and {% ["", null, expression, [], {}, ] %}
Dictionary: {% {} %}, {% {a:1} %} and {% {item: expression, " space ": "spacy", "array": [], } %}
流程控制
使用 if
/ unless
、elif
和 else
进行测试表达式
{% if some_expression %}
Rendered when the expression is truthy
{% elif else_if_expression %}
Rendered when the above is not true and the expression is truthy
{% else %}
Rendered when the above are not truthy
{% end %}
{% unless expression %}
Rendered when the expression is falsy
{% end %}
使用 for
和 else
在数组上循环
{% for item in array_value %}
Rendered content for each item
reference a property in iteration array: {% item.property %}
0-based index: {% loop.index0 %}
1-based index: {% loop.index1 %}
true if this is the first iteration: {% loop.first %}
true if this is the last iteration: {% loop.last %}
the number of iterations in the loop: {% loop.size %}
alternate items in an array, treating it as circular: {% loop.index0 | alternate(["one", "two", "three"]) %}
{% else %}
Rendered when the array did not contain any values
{% end %}
注意,在 for
循环内部,loop
变量提供了有关循环迭代的详细信息。
上下文变量
使用 with
在块内设置变量
{% with a = 1 %}
Value is {% a %}
{% end %}
函数
通过使用管道 |
运算符在模板中应用函数
{% value | function1 | function2 | function3 %}
某些函数需要一个或多个参数,可以通过括号传递
{% value | function(argument1, argument2) %}
通用函数
default(value)
:如果参数是虚假的,则返回默认值。coalesce(value)
:如果参数是null
,则返回默认值。toString
:将值转换为字符串。empty
:判断值是否为“非真”,即null
、0
、0.0
、-0.0
、""
、" "
、[]
或{}
。toJson
,toPrettyJson
:将值格式化为JSON,可以是紧凑格式或多行缩进格式。
字符串函数
length
:字符串的长度。upperCase
:将字符串转换为大写。lowerCase
:将字符串转换为小写。kebabCase
:将字符串转换为中划线命名法:lowercase-words-joined-with-dashes
。snakeCase
:将字符串转换为蛇形命名法:lowercase_words_joined_with_underscores
。camelCase
:将字符串转换为驼峰命名法:capitalizedWordsWithoutSpaces
。pascalCase
:将字符串转换为帕斯卡命名法:CapitalizedWordsWithoutSpaces
。capitalize
:将字符串的第一个字符转换为大写。capitalizeWords
:将每个单词的第一个字符转换为大写。environment
:读取环境变量。reverse
:字符串的逆序。split(splitter)
:根据splitter
在每个出现处分割字符串。lines
:将字符串分割成一个由行组成的数组。首尾空白将被删除。parseBoolean
:解析布尔值。parseInteger
:解析整数。parseDecimal
:解析十进制数。parseNumber
:解析整数或十进制数。substring(from)
,substring(from, to)
:从字符串中创建子字符串。from
是包含的,to
是不包含的。take(n)
:从字符串中取前n
个字符。drop(n)
:从字符串中删除前n
个字符。fromJson
:从JSON中解析值。abbreviate
:确保值不超过n
个字符。如果更长,值将被缩短至n-1
个字符,并后缀…
。trimLeft
,trimRight
,trim
:从字符串的左侧、右侧或两侧删除空白。matches(regex)
:检查字符串是否匹配正则表达式。replace(search, replacement)
:用替换字符串替换搜索字符串。regexReplace(search, replacement)
:用替换内容替换正则表达式匹配到的内容。替换内容可以包含$0
(整个匹配),$1
,$2
等,用于匹配的分组,以及$name
用于匹配命名的分组。contains(substring)
:字符串是否包含子字符串。startsWith(start)
,endsWith(end)
:字符串是否以给定的值开始或结束。
数组函数
length
:数组的长度。reverse
:数组的反向顺序。take(n)
:从数组中取前n
项。drop(n)
:从数组中移除前n
项。first
:数组中的第一项,如果存在的话。last
:数组中的最后一项,如果存在的话。index(n)
:数组中的第 n 项,如果存在的话。contains(value)
:数组是否包含指定的值。unique
:从数组中删除所有重复项。all
:如果所有参数都是真值,则为真,表示逻辑与(∧)。any
:如果任何参数都是真值,则为真,表示逻辑或(∨)。none
:如果所有参数都是假值,则为真。some
:如果任何参数是假值,则为真。chunked(items, overlap)
:将数组分割成数组的数组,每个子数组最多包含items
项,与上一个块重叠overlap
项。
字典函数
length
:字典的大小。containsKey(key)
:字典是否包含指定的键。containsValue(value)
:字典是否包含指定的值。keys
:字典的键。values
:字典的值。invert
:值变为键,键变为值。值只能是字符串。不保留重复值。
布尔函数
negate
:布尔值的否定,表示逻辑非(¬)。
日期/时间函数
parseFormatDateTime(parse, format)
:解析日期/时间,并按给定格式格式化。如果输入是字符串now
,则将其解析为当前时刻。否则,解析和格式化遵循 strftime 规范。
调试
可以使用 debug
语句来记录表达式及其计算结果,而不会将内容输出到模板输出中。
Template content...
{% debug some_value %}
... more template content
日志输出
[2023-03-05T11:18:56Z INFO template_cli::evaluate] Debug expression: some_value = {"b":"c"}
可以使用 assert
函数来断言表达式的预期值。如果断言失败,模板渲染将因给定的断言消息而失败,并退出程序并记录错误代码。
{% true | assert(true, "This is fine") %}
{% false | assert(true, "This is not OK") %}
模板将退出并带有错误代码,并记录输出
[2023-03-19T16:02:48Z ERROR template] ERROR: Could not render template: Assertion failed: Expected value 'true' but found 'false': This is not OK
开发
构建
cargo build
测试
cargo test
发布
访问发布工作流程。
点击 运行工作流程 按钮,并输入以下信息
- 分支:
master
- 版本: 即将发布的下一个版本,例如
1.2.3
依赖项
~14MB
~252K SLoC