Tera 中文教程:简明易懂的入门指南

Tera 是一个强大的 Rust 模板引擎,灵感来源于 Jinja2 和 Django 的模板系统。它广泛应用于 Web 开发中,用于生成动态 HTML 内容。本文将带领您从零开始,逐步了解如何在 Rust 项目中使用 Tera,包括基本设置、模板语法、高级用法以及内置的过滤器、测试和函数。


文章目录

  • Tera 中文教程:简明易懂的入门指南
  • 开始使用
  • 1. 添加 Tera 依赖
  • 2. 在代码中引入 Tera
  • 3. 查看 API 文档
  • 用法
  • 1. 加载模板
  • 2. 创建上下文
  • 3. 编译模板
  • 4. 渲染模板
  • 模板
  • 1. 基础知识
  • 2. 原始内容
  • 3. 空白控制
  • 4. 注释
  • 内置过滤器
  • 1. lower
  • 2. upper
  • 3. wordcount
  • 4. capitalize
  • 5. replace
  • 6. addslashes
  • 7. slugify
  • 8. title
  • 9. trim
  • 10. truncate
  • 内置测试
  • 1. defined
  • 2. undefined
  • 3. odd
  • 4. even
  • 5. string
  • 6. number
  • 7. divisibleby
  • 8. iterable
  • 9. object
  • 10. starting_with
  • 11. ending_with
  • 12. containing
  • 13. matching
  • 内置函数
  • 1. range
  • 2. now
  • 3. throw
  • 4. get_random
  • 5. get_env


开始使用

要在您的 Rust 项目中使用 Tera,只需按照以下步骤操作:

1. 添加 Tera 依赖

在您的 Cargo.toml 文件中添加 Tera 依赖:

[dependencies]
tera = "1.0"  # 请根据最新版本号进行调整

如果您不需要 Tera 的默认功能(如自动转义、日期处理等),可以禁用默认特性:

[dependencies]
tera = { version = "1.0", default-features = false }

2. 在代码中引入 Tera

如果您使用的是 Rust 2018 版本或更高版本,无需显式声明 extern crate。直接在您的 main.rslib.rs 文件中使用即可:

use tera::Tera;

fn main() {
    // 初始化 Tera 实例并加载模板
    let tera = match Tera::new("templates/**/*.html") {
        Ok(t) => t,
        Err(e) => {
            println!("模板解析错误: {}", e);
            std::process::exit(1);
        }
    };

    // 渲染模板
    let rendered = tera.render("hello.html", &context).unwrap();
    println!("{}", rendered);
}

如果您使用的是 Rust 2015 版本,请在文件顶部添加 extern crate tera;

extern crate tera;
use tera::Tera;

3. 查看 API 文档

Tera 提供了丰富的 API 文档,您可以在 docs.rs/tera 上查看 Tera 导出的所有内容,帮助您更好地理解和使用 Tera。


用法

使用 Tera 的主要步骤包括加载模板、创建上下文以及渲染模板。以下是一个基本的用法示例:

1. 加载模板

假设您的项目目录结构如下:

templates/
├── hello.html
├── index.html
└── products/
    ├── product.html
    └── price.html

加载模板的方法如下:

use tera::Tera;

fn main() {
    let tera = match Tera::new("templates/**/*.html") {
        Ok(t) => t,
        Err(e) => {
            println!("模板解析错误: {}", e);
            std::process::exit(1);
        }
    };
}

2. 创建上下文

上下文用于向模板传递数据。可以使用实现了 Serialize 特征的数据结构,或直接使用 tera::Context

use tera::Context;
use serde::Serialize;

#[derive(Serialize)]
struct Product {
    name: String,
}

fn main() {
    let mut context = Context::new();
    let product = Product {
        name: "Rust Book".to_string(),
    };
    context.insert("product", &product);

    // 渲染模板
    let rendered = tera.render("products/product.html", &context).unwrap();
    println!("{}", rendered);
}

3. 编译模板

为了提高渲染效率,您可以使用 lazy_static 定义一个常量 Tera 实例,只编译一次:

use tera::Tera;
use lazy_static::lazy_static;

lazy_static! {
    pub static ref TEMPLATES: Tera = {
        let mut tera = Tera::new("templates/**/*").unwrap();
        tera.autoescape_on(vec![".html", ".sql"]);
        tera.register_filter("do_nothing", do_nothing_filter);
        tera
    };
}

fn do_nothing_filter(value: &str) -> Result<String, tera::Error> {
    Ok(value.to_string())
}

fn main() {
    let rendered = TEMPLATES.render("products/product.html", &context).unwrap();
    println!("{}", rendered);
}

4. 渲染模板

渲染模板时,需要指定模板名称和上下文:

fn main() {
    let rendered = tera.render("hello.html", &context).unwrap();
    println!("{}", rendered);
}

模板

Tera 模板是一个包含变量和表达式的文本文件,在渲染时这些变量和表达式会被实际的值替换。模板语法分为表达式、语句和注释,以下是详细介绍。

1. 基础知识

Tera 模板中的标记有三种类型,且不能更改其分隔符:

  • 表达式:使用 {{}} 包围,用于输出变量或表达式的结果。
  • 语句:使用 {%%} 包围,用于控制流程,如循环、条件判断等。
  • 注释:使用 {##} 包围,用于添加注释,注释内容不会被渲染。

2. 原始内容

使用 raw 块可以让 Tera 将其中的所有内容视为纯文本,不进行模板解析:

{% raw %}
  Hello {{ name }}
{% endraw %}

上面的模板将渲染为:

Hello {{ name }}

3. 空白控制

Tera 提供了方便的空白控制选项,可以在语句前后删除多余的空格或换行:

  • {{--%}:在表达式前后删除空格。
  • {%--%}:在语句前后删除空格。
  • {#--#}:在注释前后删除空格。

示例:

{% set my_var = 2 -%}
{{ my_var }}

渲染结果将不包含设置语句后的换行。

4. 注释

要在模板中添加注释,请使用 {##} 包围内容:

{# 这是一个注释 #}

注释内容不会出现在渲染结果中。


内置过滤器

过滤器用于修改表达式的输出结果。Tera 内置了多种过滤器,以下是部分常用过滤器及其使用方法。

1. lower

将字符串转换为小写。

{{ "HELLO World" | lower }}

输出:

hello world

2. upper

将字符串转换为大写。

{{ "hello world" | upper }}

输出:

HELLO WORLD

3. wordcount

计算字符串中的单词数。

{{ "Hello world from Tera" | wordcount }}

输出:

4

4. capitalize

将字符串的首字母大写,其余字母小写。

{{ "hello WORLD" | capitalize }}

输出:

Hello world

5. replace

替换字符串中的指定部分。

{{ "Hello Robert" | replace(from="Robert", to="Bob") }}

输出:

Hello Bob

6. addslashes

在引号前添加反斜杠。

{{ "I'm using Tera" | addslashes }}

输出:

I\'m using Tera

7. slugify

将字符串转换为适合 URL 使用的格式。

{{ "-Hello world! " | slugify }}

输出:

hello-world

8. title

将每个单词的首字母大写。

{{ "hello  bar" | title }}

输出:

Hello  Bar

9. trim

去除字符串前后的空白。

{{ "   Hello World   " | trim }}

输出:

Hello World

10. truncate

截断字符串到指定长度,并添加省略号(默认为 “…”):

{{ "Hello Tera World" | truncate(length=10) }}

输出:

Hello Ter…

可以自定义结尾字符:

{{ "Hello Tera World" | truncate(length=10, end="") }}

输出:

Hello Tera

内置测试

测试用于在模板中进行条件判断。以下是 Tera 内置的主要测试及其使用方法。

1. defined

检查变量是否已定义。

{% if user is defined %}
    Hello, {{ user }}!
{% endif %}

2. undefined

检查变量是否未定义。

{% if user is undefined %}
    Hello, guest!
{% endif %}

3. odd

检查数字是否为奇数。

{% if age is odd %}
    You are odd.
{% endif %}

4. even

检查数字是否为偶数。

{% if age is even %}
    You are even.
{% endif %}

5. string

检查变量是否为字符串。

{% if title is string %}
    {{ title | upper }}
{% endif %}

6. number

检查变量是否为数字。

{% if price is number %}
    Price: {{ price }}
{% endif %}

7. divisibleby

检查数字是否能被指定数整除。

{% if rating is divisibleby(2) %}
    Even rating.
{% endif %}

8. iterable

检查变量是否可迭代(如数组、对象)。

{% if items is iterable %}
    {% for item in items %}
        {{ item }}
    {% endfor %}
{% endif %}

9. object

检查变量是否为对象(可迭代的键值对)。

{% if user is object %}
    Username: {{ user.username }}
{% endif %}

10. starting_with

检查字符串是否以指定前缀开始。

{% if path is starting_with("x/") %}
    Path starts with x/
{% endif %}

11. ending_with

检查字符串是否以指定后缀结束。

{% if filename is ending_with(".html") %}
    HTML File
{% endif %}

12. containing

检查变量是否包含指定内容。

{% if username is containing("xXx") %}
    Invalid username.
{% endif %}

13. matching

检查字符串是否匹配指定正则表达式。

{% if name is matching("^[Qq]ueen") %}
    Her Royal Highness, {{ name }}
{% elif name is matching("^[Kk]ing") %}
    His Royal Highness, {{ name }}
{% else %}
    {{ name }}
{% endif %}

内置函数

Tera 提供了一些全局函数,帮助您在模板中执行常用任务。

1. range

生成一个整数数组,类似于 Python 的 range 函数。

{% for i in range(end=5) %}
    {{ i }}
{% endfor %}

输出:

0
1
2
3
4

可以指定起始点和步长:

{% for i in range(start=1, end=10, step_by=2) %}
    {{ i }}
{% endfor %}

输出:

1
3
5
7
9

2. now

获取当前的日期和时间。

{{ now() | date }}

输出:

2023-08-15

可以指定格式和时区:

{{ now() | date(format="%Y-%m-%d %H:%M", timezone="Asia/Shanghai") }}

输出:

2023-08-15 14:30

3. throw

在模板中强制触发错误,并显示指定消息。

{% throw "强制错误发生!" %}

渲染此模板时,将抛出错误并显示 “强制错误发生!”。

4. get_random

生成指定范围内的随机整数。

{{ get_random(start=1, end=100) }}

输出:

42

5. get_env

获取环境变量的值。

{{ get_env(name="HOME") }}

输出:

/home/user

如果环境变量不存在,可以提供默认值:

{{ get_env(name="NON_EXISTENT_VAR", default="默认值") }}

输出:

默认值