Askama模板引擎语法详解:从基础到高级用法
Askama是一个基于Rust的模板引擎,它结合了Rust的类型安全性和Jinja2风格的模板语法。本文将全面介绍Askama的模板语法,帮助开发者高效地构建动态内容。
变量与常量使用
变量访问
在Askama模板中,变量通过模板上下文类型定义。使用点号(.)可以访问变量的属性和方法:
{{ name }} {# 访问上下文中的name字段 #}
{{ user.name }} {# 访问user字段的name属性 #}
变量读取遵循Rust的借用规则,确保内存安全。
常量引用
可以在模板中直接使用Rust代码中定义的常量:
// Rust代码中定义常量
pub const MAX_USERS: usize = 100;
模板中引用方式:
<p>最大用户数:{{ crate::MAX_USERS }}</p>
变量声明与控制结构
变量赋值
使用let
或set
关键字声明变量:
{% let username = user.name %}
{% let length = username.len() %}
支持变量遮蔽:
{% let foo = "初始值" %}
{{ foo }} {# 输出"初始值" #}
{% let foo = "新值" %}
{{ foo }} {# 输出"新值" #}
条件判断
支持完整的条件逻辑:
{% if users.is_empty() %}
没有用户
{% elif users.len() == 1 %}
1个用户
{% else %}
{{ users.len() }}个用户
{% endif %}
循环迭代
遍历集合:
<ul>
{% for user in users %}
<li>{{ loop.index }}. {{ user.name }}</li>
{% endfor %}
</ul>
循环中可用的特殊变量:
loop.index
: 当前迭代索引(从1开始)loop.index0
: 当前迭代索引(从0开始)loop.first
: 是否第一次迭代loop.last
: 是否最后一次迭代
高级模板功能
过滤器应用
Askama提供了强大的过滤器系统:
{{ content|escape|upper }} {# 先转义再转为大写 #}
自定义过滤器:
- 在上下文作用域内创建
filters
模块 - 定义过滤器函数
- 内置过滤器优先于同名自定义过滤器
模板继承
创建基础模板:
<!DOCTYPE html>
<html>
<head>
<title>{% block title %}默认标题{% endblock %}</title>
</head>
<body>
{% block content %}{% endblock %}
</body>
</html>
子模板扩展:
{% extends "base.html" %}
{% block title %}子页面标题{% endblock %}
{% block content %}
<h1>页面内容</h1>
{{ super() }} {# 渲染父模板内容 #}
{% endblock %}
宏定义
创建可重用组件:
{% macro alert(message, type="info") %}
<div class="alert alert-{{ type }}">
{{ message }}
</div>
{% endmacro %}
{# 使用宏 #}
{% call alert("操作成功", "success") %}
安全与转义
Askama默认对HTML内容进行转义,防止XSS攻击:
{{ user_input }} {# 自动转义HTML特殊字符 #}
{{ html_content|safe }} {# 禁用转义 #}
转义规则:
- 默认对
.html
,.htm
,.xml
扩展名的模板启用转义 - 可通过
#[template(escape = "none")]
禁用转义 - 转义字符包括:
<
,>
,&
,"
,'
性能优化技巧
空白控制
精确控制模板输出的空白字符:
{% if condition -%} {# 删除左侧空白 #}
内容
{%- endif %} {# 删除右侧空白 #}
控制级别优先级:
- 内联控制(
-
,+
,~
) - 派生属性(
#[template(whitespace = "suppress")]
) - 配置文件设置
递归结构处理
处理树形等递归数据结构时,建议:
- 实现自定义迭代器
- 使用简单循环而非递归
- 必要时直接调用
.render()
#[derive(Template)]
#[template(source = "{% for item in children %}{{ item }}{% endfor %}")]
struct TreeNode {
name: String,
children: Vec<TreeNode>,
}
最佳实践
- 将复杂逻辑放在Rust代码中而非模板内
- 使用宏和模板继承提高代码复用
- 合理使用空白控制保持输出整洁
- 始终考虑HTML转义安全性
- 对大型模板使用
include
分块管理
Askama通过结合Rust的强类型系统和灵活的模板语法,为开发者提供了安全高效的模板解决方案。掌握这些语法特性,可以构建出既安全又易于维护的动态内容。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考