Tera 模板引擎语法与全局上下文变量

更新于 2026-08-28

写模板经常遇到两种麻烦:一是「盲人摸象」,不知道当前页面到底有哪些变量可以调;二是缺少必要的页面函数,辛辛苦苦把 Markdown 编译成了 HTML,页面上一看却把 <h1><p> 标签当纯文本原样打印了出来——排查半天,才发现是缺少 safe 之类的过滤器。

RustPress 选用 Tera 作为模板渲染引擎。Tera 深度借鉴了 Python 社区的 Jinja2 和 Django 模板哲学,语法直观优雅,同时在 Rust 编译器底层完成了极致的速度优化。

本篇系统梳理 Tera 的核心语法、常用过滤器,以及 RustPress 运行时自动注入的全量上下文变量清单


一、Tera 核心语法

1. 变量输出与安全转义

<!-- 普通变量:默认会自动进行 HTML 转义,防止 XSS -->
<h1>{{ page.title }}</h1>

<!-- 输出编译后的 HTML 正文:必须加 | safe 过滤器,否则标签会被转义为纯源码 -->
<div class="prose">
    {{ page.content | safe }}
</div>

2. 条件分支(if / elif / else

{% if page.draft %}
    <span class="badge-draft">草稿</span>
{% elif page.is_pinned %}
    <span class="badge-pinned">置顶</span>
{% else %}
    <span class="badge-normal">普通</span>
{% endif %}

3. 循环遍历(for ... in

<ul>
{% for tag in page.tags %}
    <li><a href="/tag/{{ tag }}/"># {{ tag }}</a></li>
{% empty %}
    <li>暂无标签</li>
{% endfor %}
</ul>

for 循环内部,Tera 自动提供了实用的循环状态变量:

  • loop.index:从 1 开始的计数;
  • loop.index0:从 0 开始的索引;
  • loop.first:布尔值,是否为第一项;
  • loop.last:布尔值,是否为最后一项。

4. 模板继承与插槽(extends & block

<!-- 子模板 post.html -->
{% extends "base.html" %}

{% block title %}{{ page.title }} - {{ site.name }}{% endblock title %}

{% block content %}
<main class="container mx-auto px-4 py-8">
    <article>
        <h1>{{ page.title }}</h1>
        <div class="content">{{ page.content | safe }}</div>
    </article>
</main>
{% endblock content %}

二、常用过滤器(Filters)速查清单

  • safe(安全 HTML 标记)
    • 语法示例{{ page.content | safe }}
    • 说明效果:标记为可信的富文本 HTML,禁用默认转义,直接渲染 HTML 标签。
  • default(缺省默认值兜底)
    • 语法示例{{ site.author.maxim | default(value="博学审问") }}
    • 说明效果:当目标变量为 null、undefined 或空时,采用指定的兜底默认值。
  • truncate(字符串截断)
    • 语法示例{{ post.description | truncate(length=80) }}
    • 说明效果:截取前 80 个字符并在末尾自动拼接省略号 ...
  • slice(数组切片截取)
    • 语法示例{% for p in posts | slice(end=5) %}
    • 说明效果:截取数组的前 5 个元素进行遍历。
  • length(长度/计数统计)
    • 语法示例{{ page.tags | length }}
    • 说明效果:计算并返回数组元素个数或字符串字符总数。
  • lower / upper(大小写转换)
    • 语法示例{{ post.slug | lower }}
    • 说明效果:将文本统一转换为全小写或全大写。
  • first / last(首尾元素提取)
    • 语法示例{{ page.tags | first }}
    • 说明效果:快速提取数组的第一项(首元素)或最后一项(末元素)。

三、RustPress 全局上下文变量大盘点

在渲染每个页面时,RustPress 会把以下数据自动注入 Tera 上下文:

1. site 对象(全站全局配置)

  • site.name:网站名称(如 "艺述论"
  • site.description:网站描述与 Slogan
  • site.domain:正式线上域名(如 "https://yishulun.com"
  • site.base_url:当前环境基准 URL
  • site.author.name:作者姓名
  • site.author.bio:作者一句话简介
  • site.author.maxim:作者座右铭
  • site.author.avatar:作者头像路径
  • site.author.email:联系邮箱
  • site.author.donate_qrcode:赞赏码图片路径
  • site.social:包含 github, twitter, youtube, zhihu, bilibili, rss 等各平台链接字典
  • site.icp_license:备案号
  • site.start_year:创站年份

2. page 对象(当前渲染页面的元数据)

  • page.title:文章或专栏标题
  • page.content:Markdown 编译后的 HTML 正文
  • page.date_ymd:发布日期(YYYY-MM-DD
  • page.create_time_hm:发布时间(HH:MM
  • page.tags:标签列表数组
  • page.categories:分类层级列表数组
  • page.draft:布尔值,是否为草稿
  • page.url:当前页面的相对访问路径(如 "/2026/01.html"
  • page.description:文章摘要
  • page.cover:封面图片路径
  • page.comments:布尔值,是否开启评论区

3. 数据集合对象

  • posts / all_posts:文章对象列表;
  • columns:全站专栏元数据数组;
  • features:全局功能开关(features.search, features.comments, features.analytics 等);
  • analytics.google_id:GA4 衡量 ID。

Tera 模板引擎提供了强大的逻辑控制与过滤器支持,赋予了前端极大的布局自由度;但如果在 HTML 模板中强行编写深度嵌套的多层计算或复杂字符串清洗,会破坏模板的可读性与渲染性能。模板层仅负责「如何将已有数据渲染为 HTML」;所有复杂的数据清洗、排序算法与倒分页计算等,均在 Rust 语言里面预先算好,并直接注入上下文。模板引擎只负责视图排版,数据计算则交给专业的后端语言。

下一篇,我们来看如何从零手搓一套属于自己的专属主题。

金石碼农

金石碼农

大学计算机讲师,腾讯云最具价值专家(TVP),《小程序从0到1》《微信小游戏开发》作者,微信学堂讲师,极客时间荣誉讲师。公众号:艺述论。

北京, 中国

扫一扫,添加作者微信

微信二维码

评论

登录 GitHub 后即可发表评论
加载评论中...