#mustache #templating #compile-time #web

bart

受 Mustache 启发的编译时模板

7 个版本

0.1.6 2023 年 6 月 21 日
0.1.4 2017 年 7 月 14 日
0.1.1 2017 年 6 月 20 日
0.1.0 2017 年 2 月 3 日
0.0.1 2017 年 1 月 7 日

模板引擎 中排名第 81

Download history 40/week @ 2024-03-11 18/week @ 2024-03-18 41/week @ 2024-03-25 72/week @ 2024-04-01 17/week @ 2024-04-08 18/week @ 2024-04-15 38/week @ 2024-04-22 20/week @ 2024-04-29 15/week @ 2024-05-06 23/week @ 2024-05-13 28/week @ 2024-05-20 22/week @ 2024-05-27 22/week @ 2024-06-03 14/week @ 2024-06-10 24/week @ 2024-06-17 34/week @ 2024-06-24

每月下载 98
4 Crates 中使用(直接使用 2 个)

MIT 许可证

17KB
204 代码行

Build Status

Bart 是一个受 Mustache 启发的 Rust 编译时模板语言。它通过将模板静态编译成高效的代码,并在编译时执行完整的变量解析和类型检查,来发挥 Rust 的优势。

Cargo 依赖项

要使用 Bart,请将这些依赖项添加到您的 Cargo.toml

[dependencies]
bart = "0.1.4"
bart_derive = "0.1.4"

示例

给定模板文件 hello_world.html

Hello {{name}}

我们可以编写以下程序

#[derive(bart_derive::BartDisplay)]
#[template = "hello_world.html"]
struct HelloWorld<'a> {
    name: &'a str,
}

fn main() {
    print!("{}", &HelloWorld { name: "World" });
}

要编译此示例程序,您需要在您的 Cargo.toml 中将 bartbart_derive 作为依赖项添加。

运行此程序将输出

Hello World

您可以通过克隆此存储库并执行 cargo run --example hello_world 来运行此示例。

逐行分析

#[derive(BartDisplay)]

Bart 的程序员接口是在 bart_derive Crates 中定义的过程宏,它实现了对 #[derive(bart_derive::BartDisplay)] 的支持。它必须添加到您的 Cargo.toml 中。由于 bart_derive 生成的代码依赖于 bart Crates,因此您还需要将此拉入作为依赖项。

使用 bart_derive::BartDisplay 根据以下模板和结构体生成 Display 特性的实现。

#[template = "hello_world.html"]

bart_derive 会读取 hello_world.html 并用它来生成模板渲染代码。给定文件名是相对于您的 crate 根目录的,所以,例如,如果您想将模板保存在 src/ 目录中,您必须指定 #[template = "src/hello_world.html"]

还可以使用 template_string 在行内指定模板: #[template_string = "Hello {{name}}"]

struct HelloWorld<'a> {
    name: &'a str,
}

要在模板中插值的值将从给定的 struct 中解析。在这种情况下,{{name}} 将解析为该结构体的 name 字段。要插值的字段必须实现 Display 特性。

fn main() {
    print!("{}", &HelloWorld { name: "World" });
}

如上所述,bart_derive 现已为 HelloWorld 生成 impl Display。这意味着我们可以将 HelloWorld 的实例传递给 print!write!format! 等等。模板使用提供的数据进行渲染,生成 Hello World 并输出到标准输出。

语言参考

Bart 模板语言受到了 Mustache 的启发。(Bart 是挪威语中胡子的意思。)

输入会原样复制,除了标签。标签以 {{ 开始,以 }} 结束。

插值

最简单的标签是插值标签,其中包含数据引用。对于模板 Hello {{name}}{{name}} 被识别为插值标签,并且 name 被解析为给定 struct 的一个字段。该字段必须实现 Display 特性。可以使用 . 来引用嵌套 struct 中的字段;{{name.surname}}

插值标签被HTML转义,因此对于模板 Hello {{name}},如果 {{name}}Bobby <tags>,输出将是 Hello Bobby &lt;tags>

原始/未转义的插值

有时也需要故意包含未转义的HTML内容。使用三重标签 {{{}}} 来实现此功能:如果 nameBobby <tags>,则 Hello {{{name}}} 将渲染 Hello Bobby <tags>

迭代

可以迭代实现了 IntoIterator 的任何东西

<ul>
{{#values}}
    <li>{{.}}</li>
{{/values}}
</ul>

使用 {{.}} 来引用当前值。例如,如果 values 是一个 Vec<i32>,则 {{.}} 将依次引用所包含的每个 i32 值。在遍历一组结构时,使用一个 . 前缀来引用成员

<ul>
{{#people}}
    <li>{{.name}} ({{.age}})</li>
{{/people}}
</ul>

可以利用 OptionResult 上的 IntoIterator 实现来在 Bart 迭代中使用它们。

作用域

与迭代类似,可以通过指定尾随点进入变量的作用域

{{#person.}}
    {{.name}} ({{.age}})
{{/person}}

还可以完全限定每个引用

{{person.name}} ({{person.age}})

在嵌套作用域中,使用多个前导点来退出

{{#department.}}
    {{#head.}}
        {{.name}}, head of the {{..name}} department.
    {{/head}}
{{/department}}

未限定名称,即不带前导点的名称,将始终在最高作用域中解析。

相同的范围规则也适用于迭代作用域。

依赖项

~660KB
~13K SLoC