4个版本

0.2.2 2024年1月24日
0.2.1 2023年12月6日
0.2.0 2023年9月28日
0.1.0 2023年7月3日

#1775 in 过程宏


stilts中使用

MIT许可证

95KB
2K SLoC

Stilts

Documentation Package

Stilts是一种受到Askama启发的模板语言。这意味着它具有Rust编译器提供的所有类型安全性。它仍然与Jinja有松散的联系,但它采用了更符合Rust的表达式语法。

这个项目还处于非常早期阶段,我只是因为我喜欢Askama,但我觉得可以通过允许在模板表达式中使用更多Rust特定语法来改进它。如果您有任何建议、功能、问题或其他任何东西,请随时提出问题。我特别需要额外帮助编写单元测试,并且愿意与其他人合作完成这项工作。

指南

查看书籍以获取深入文档。

工作原理

Stilts使用在结构上使用过程推导宏来生成模板渲染代码,这使得模板代码可以通过Rust编译器进行正确性检查。

快速示例

以下是一些定义模板的Rust代码示例

use stilts::Template;

#[derive(Template)] // This derive macro will generate the template rendering code
#[stilts(path = "index.html")] // based on the contents of the given template path
struct IndexPage<'a> {
    some_data: &'a str, // The fields on a struct are the variables 
}                       // you want to use in your template

以下是index.html可能的样子

<!DOCTYPE html>
<html>
    <body>
        <h1>My Index Page</h1>
        {% some_data %} <!--This will print some_data to the template here using 
                            the types implementaion of the Display trait-->
    </body>
</html

关于Stilts表达式

在Stilts中,一个表达式由两种变体组成:singleblock表达式。单个表达式是任何位于分隔符{%%}内的内容。而块表达式有一个开头的单个表达式和一个带有某种内容的结尾单个表达式。例如

{% for i in 0..10 %}
    This will be repeated 10 times
    {% i %}
    And I can put other expressions inside
{% end %}

如果你之前使用过Askama或Jinja,可能会注意到,通常要渲染某个值,你必须使用一组不同的定界符,例如{{ some_data }}。但在这里,Stilts只有一个定界符集{% some_data %}

那么我们如何确定用户是想渲染某些内容还是仅仅编写一些代码呢?答案是,通过判断定界符内的Rust代码是表达式还是语句。在Rust中,表达式总是产生一个值,而语句则不会。

因此,如果我们作为用户想要编写一些代码但不将其渲染到模板中,我们只需要添加一个分号。现在{% some_data; %}是一个语句,而不是表达式,这意味着Stilts会将它作为代码插入到模板渲染代码中,而不是渲染到最终的模板中。这对许多Rust开发者来说很熟悉,因为我们可以在函数内部通过仅以表达式结束来省略return关键字。

这也意味着你可以在定界符内放置任何任意的Rust表达式或语句。例如{% let myval = some_data.split(' ').filter(|s| s != "abcd"); %}。但你不仅限于单行,你可以将它们分成任意多行。

{% fn my_useful_func() {
    // do some stuff
} %}

特性

  • 语法类似于Jinja,但更接近Rust
  • 利用Rust的类型系统验证你的代码
  • 实现与Askama相当的性能,后者已经非常出色
  • 良好的错误消息和格式,特别是具有可选的华丽特性
  • 在稳定的Rust上运行

支持的模板构造

  • 继承
  • for循环
  • if/else if/else
  • match表达式
  • 包含语句
  • 变量(允许任意Rust表达式和语句的结果)
  • 导入作用域的有用扩展特质
  • 可配置的HTML转义选项

目标

  • 创建一个既熟悉给Jinja用户也熟悉Rust开发者的模板语言
  • 具有良好的错误报告和消息,以及有用的错误位置。

其他东西

在工具目录中有一个正在进行中的tree-sitter解析器实现。如果你知道如何更好地使其工作,那将会非常酷。


lib.rs:

生成模板的Rust代码的 derive 宏

依赖关系

~1.5–3MB
~54K SLoC