配置
在编译时,如果启用了 config 特性(默认启用),Askama 会从 crate 根目录(即 Cargo.toml 所在目录)下的 askama.toml 文件中读取可选的配置值。目前,该配置涵盖模板搜索目录、自定义语法配置和转义器配置。
以下示例文件展示了默认配置:
[general]
# Directories to search for templates, relative to the crate root.
dirs = ["templates"]
# Unless you add a `-` in a block, whitespace characters won't be trimmed.
whitespace = "preserve"
请注意,dirs 支持通配符(*)语法。因此你可以写成:
[general]
dirs = ["templates/*"]
甚至:
[general]
dirs = ["templates/**"]
如果你需要包含子文件夹的话。
空白字符控制
在默认配置下,你可以使用 - 操作符来指示在块之前或之后抑制空白字符。例如:
<div>
{%- if something %}
Hello
{% endif %}
在上面的模板中,只有 <div> 和 {%- 之间的空白字符会被抑制。如果你将 whitespace 设置为 "suppress":
[general]
whitespace = "suppress"
那么每个块前后的空白字符将默认被抑制。要保留空白字符,可以使用 + 操作符:
{% if something +%}
Hello
{%+ endif %}
在这个例子中,Hello 将被换行符包围。
还有第三种可能:如果你希望抑制所有空白字符,但保留一个,可以使用 ~:
{% if something ~%}
Hello
{%~ endif %}
需要注意的是,如果被修剪的字符中包含换行符,那么最终保留下来的唯一字符将是一个换行符。
如果你希望这是默认行为,可以将 whitespace 设置为 "minimize":
[general]
whitespace = "minimize"
需要注意的是,也可以直接在 template 派生过程宏中配置 whitespace:
#![allow(unused)]
fn main() {
#[derive(Template)]
#[template(whitespace = "suppress")]
pub struct SomeTemplate;
}
如果你直接在 template 派生过程宏中配置了 whitespace,它将优先于配置文件中的设置。因此,在这种情况下,即使你在配置文件中设置了 whitespace = "minimize",该模板也会被替换为 suppress。
自定义语法
以下示例定义了两个自定义语法:
[general]
default_syntax = "foo"
[[syntax]]
name = "foo"
block_start = "%{"
comment_start = "#{"
expr_end = "^^"
[[syntax]]
name = "bar"
block_start = "%%"
block_end = "%%"
comment_start = "%#"
expr_start = "%{"
一个语法块至少包含 name 属性,用于在项目中唯一标识该语法。
目前可以使用以下键来自定义模板语法:
block_start, defaults to{%block_end, defaults to%}comment_start, defaults to{#comment_end, defaults to#}expr_start, defaults to{{expr_end, defaults to}}
值必须至少为两个字符长。如果省略某个键,则使用默认语法中的对应值。
转义器
以下是一个自定义转义器的示例:
[[escaper]]
path = "::tex_escape::Tex"
extensions = ["tex"]
一个转义器块包含 path 和 extensions 属性。path 包含一个 Rust 标识符,该标识符必须在使用该转义器的模板的作用域内可见。此类型必须实现 Escaper trait。
extensions 定义了一个文件扩展名列表,当模板使用这些扩展名时会触发该转义器。扩展名的匹配顺序从第一个配置的转义器开始,最后是 HTML(扩展名 html、htm、xml、j2、jinja、jinja2)和纯文本(无转义;扩展名 md、yml、none、txt 和空字符串)的默认转义器。请注意,这意味着你也可以定义其他转义器,将不同的扩展名匹配到同一个转义器。
然后,你就可以使用带有该扩展名的模板,或者在模板中使用带有你扩展名名称的 escape 过滤器:
{{ some_string|escape("tex") }}
举个例子,我们希望 .js 文件像 “txt” 文件一样被处理。可以这样做:
[[escaper]]
path = "askama::filters::Text"
extensions = ["js"]
Text 实现了 Escaper trait,因为我们不需要对 .js 文件进行任何转义,所以直接使用它。
你可以在 askama 仓库中查看custom escaper example。