26 个版本

使用旧的 Rust 2015

0.2.15 2017年4月11日
0.2.12 2017年1月12日
0.2.10 2016年12月22日
0.1.4 2016年5月23日
0.0.15 2016年5月20日

#345模板引擎

48 每月下载次数

MIT/Apache

130KB
3K SLoC

crates.io Build Status

{% Incrust %}

Incrust 是一个受 Jinja2 启发的 Rust 编写的模板引擎。

实际上,它是一个 Jinja2DjangoTwigSwigLiquid(以及可能的其他)模板引擎星系,使用类似的方法。

不稳定

实现处于非常早期阶段,API 正在变化。

请注意,Incrust 目前需要 Rust 编译器的夜间版本。

安装

Incrust 可在 crates.io 上找到,并可以像这样包含到您的 Cargo 启用项目中

[dependencies]
incrust = "=0.2.15"

为了方便使用 hashmaps,您可以使用 maplit

然后您需要设置您的环境

#[macro_use]
extern crate maplit;
extern crate incrust;

use incrust::ex;

fn create_env() -> Incrust {
    use incrust::{Incrust, FilesystemLoader};

    let mut instance = Incrust::default();
    instance.loaders.push(FilesystemLoader::new("./assets/tpl"));
    instance
}

fn main() {
    let incrust = create_env();
    let args = hashmap!{ "name".into() => ex("World") };
    incrust.render("hello", &args).unwrap();
}

尽管 Incrust 有智能加载器,但它也可以用作高级格式化器,直接从字符串模板渲染

let args = hashmap!{ "name".into() => ex("World") };
incrust.render_text("Hello, {{ name | e }}!", &args).unwrap();
// or with prepared template
let hello = incrust.parse("Hello, {{ name | e }}!");
incrust.render_parsed(&hello, &args).unwrap();

语法示例

注释

<p>Visible {# partially #} paragraph</p>
<p>Visible  paragraph</p>

转义

Example: {% raw %}{{ mustaches }}{% endraw %}
Example: {{ mustaches }}

字面量

Braces: {{ "{{" }}
Pi: {{ 3.1415926 }}
Braces: {{
Pi: 3.1415926

过滤器

let args = hashmap!{ "title".into() => ex("<Cats & Dogs>") };
<h1>{{ title | escape }}</h1>
<h1>&lt;Cats &amp; Dogs&gt;</h1>

表达式

let args = hashmap!{
    "what".into() => ex("Hello"),
    "who".into() => ex("World")
};
Say: "{{ what + ", " + who }}!"
Say: "Hello, World!"
let args = hashmap!{
    "alpha".into() => ex(6isize),
    "omega".into() => ex(7f64)
};
The answer is {{ alpha * omega }}
The answer is 42

延迟布尔评估

Amount: {{ amount and ("" + amount + " pcs") or "-" }}
assert_eq!("Amount: 6 pcs", incrust.render("tpl", &hashmap!{ "amount".into() => ex(6isize) }).unwrap());
assert_eq!("Amount: -", incrust.render("tpl", &hashmap!{ "amount".into() => ex(0isize) }).unwrap());

条件语句

String {% if "" %}has chars{% else %}is empty{% endif %}
It's {% if False %}false{% elif True %}true{% endif %}
String is empty
It's true

For 循环语句

let args = hashmap!{ "fruits".into() => ex(vec![ex("Orange"), ex("Apple"), ex("Banana")]) };
    <ul>
    {%- for fruit in fruits %}
        <li>{{ loop.index }}. {{ fruit | e }}</li>
    {%- endfor %}
    </ul>
    <ul>
        <li>1. Orange</li>
        <li>2. Apple</li>
        <li>3. Banana</li>
    </ul>

模板继承

let args = hashmap!{ "parent_layout".into() => ex("default") };
incrust.render("template", &args).unwrap()

default.tpl

<body>
    <h1>{% block title %}Default title{% endblock %}</h1>
    <main>
    {%- block body %}
        <p>Default body<p>
    {%- endblock %}
    </main>
</body>

template.tpl

{% extends parent_layout %}
{% block title -%}
    New title
{%- endblock %}

输出

<body>
    <h1>New title</h1>
    <main>
        <p>Default body<p>
    </main>
</body>

包含

let args = hashmap!{ "menu".into() => ex("default_menu") };
assert_eq!(expected, incrust.render("tpl", &args).unwrap());

default_menu.tpl

    <ul>
        <li><a href="/">Home</a></li>
        <li><a href="/about">About Us</a></li>
    </ul>

template.tpl

<nav>
    {%- include menu -%}
</nav>

<h1>Body</h1>

输出

<nav>
    <ul>
        <li><a href="/">Home</a></li>
        <li><a href="/about">About Us</a></li>
    </ul>
</nav>

<h1>Body</h1>

替代方案

如果您正在寻找项目的模板引擎,您还可以查看这些项目。

具有类似语法

其他

许可证

许可以下之一

贡献

除非您明确表示,否则您有意提交给作品包含在内的任何贡献,如 Apache-2.0 许可证中定义的,将按上述方式双重许可,没有任何附加条款或条件。

依赖项

~1.5MB
~17K SLoC