Zola 分类系统(Taxonomies)完全指南:从配置文件、内容标注到模板渲染
【免费下载链接】zolaA fast static site generator in a single binary with everything built-in. https://www.getzola.org项目地址: https://gitcode.com/GitHub_Trending/zo/zola
Zola 内置了功能完整的分类系统(Taxonomies),让你可以按照任意自定义维度对内容进行分组,例如博客常见的标签(tags)与分类(categories),以及电影网站中的导演、类型、奖项、上映年份等。本文以 Zola 官方文档的 Taxonomies 章节为骨架,结合当前仓库的源码实现(配置结构、路径生成、内容收集)与测试站点的实际用法,系统讲解 Taxonomies 的定义、六个配置项、内容标注方式、输出路径规则与模板渲染方法,读完即可在自己的 Zola 站点中完整落地一套分类体系。
三个核心概念:Taxonomy、Term 与 Value
在深入配置之前,先明确三个贯穿全文的基础概念:
- Taxonomy(分类维度):用于对内容分组的一个类别,例如 "tags"(标签)、"categories"(分类)。
- Term(分类项):某个分类维度下的一个具体分组,例如标签 "rust"、分类 "教程"。
- Value(内容值):可以关联到某个 Term 的内容条目,通常就是一篇页面或文章。
电影网站示例
假设你要构建一个展示电影信息的网站,可以使用如下分类维度:
- Director(导演)
- Genres(类型)
- Awards(奖项)
- Release year(上映年份)
在构建时,Zola 会为每个分类维度生成页面,列出该维度下所有已知的 Term,并把每个 Term 链接到所有关联的内容。例如下面三部电影的分类关系:
- Shape of water Value - Director ............................ Taxonomy - Guillermo Del Toro Term - Genres .............................. Taxonomy - Thriller Term - Drama Term - Awards .............................. Taxonomy - Golden globe Term - Academy award Term - BAFTA Term - Release year ........................ Taxonomy - 2017 Term - The Room Value - Director ............................ Taxonomy - Tommy Wiseau Term - Genres .............................. Taxonomy - Romance Term - Drama Term - Release Year ........................ Taxonomy - 2003 Term - Bright Value - Director ............................ Taxonomy - David Ayer Term - Genres .............................. Taxonomy - Fantasy Term - Action Term - Awards .............................. Taxonomy - California on Location Awards Term - Release Year ........................ Taxonomy - 2017 Term在这个例子中,Release year分类维度页面会包含指向 2003 和 2017 两个 Term 页面的链接;而 2017 这个 Term 页面则会同时列出《Shape of Water》和《Bright》两部电影。也就是说,Zola 在构建时会自动完成「维度 → Term → 内容」三级页面的生成与互链。
配置 Taxonomies
六个配置变量
每个 Taxonomy 在zola.toml(或config.toml)中支持六个变量:
| 变量 | 类型 | 说明 |
|---|---|---|
name | 字符串(必填) | 用于 URL 中的名称,通常使用复数形式(如 tags、categories) |
paginate_by | 数字(可选) | 若设置,每个 Term 页面将按此数量进行分页 |
paginate_path | 字符串(可选) | 若设置,分页页面使用该路径,页码会追加在其后;默认如page/1 |
feed | 布尔值(可选) | 若为true,为每个 Term 生成 feed(默认是 Atom) |
lang | 字符串(可选) | 仅多语言站点使用,指明该分类维度属于哪种语言 |
render | 布尔值(可选) | 若为false,不渲染分类维度页面与单个 Term 页面 |
从源码看,这六个字段对应 TaxonomyConfig 结构体中的定义,其中render与feed的默认值分别为true和false(见默认实现)。此外,结构体中还有一个slug字段,它是由name根据配置的 slugify 策略自动派生的(在 slugify_taxonomies 中为每个语言的 taxonomies 统一计算),无需手动配置。
两个与分页相关的方法也值得注意:
is_paginated():仅当paginate_by被设置且大于 0 时返回true(见 taxonomies.rs),所以配置paginate_by = 0等价于不启用分页;paginate_path():当未配置时返回默认值"page",最终分页 URL 形如/tags/page/1(见 taxonomies.rs)。
配置文件位置与两种示例
⚠️ 必须将taxonomies键放在配置文件的**主区块(main section)**中,而不是[extra]区块中。
示例 1:单语言站点
taxonomies = [ { name = "director", feed = true}, { name = "genres", feed = true}, { name = "awards", feed = true}, { name = "release-year", feed = true}, ]示例 2:多语言站点
# These taxonomies go in the main section taxonomies = [ {name = "director", feed = true}, {name = "genres", feed = true}, {name = "awards", feed = true}, {name = "release-year", feed = true}, ] [languages.fr] taxonomies = [ {name = "director", feed = true}, {name = "genres", feed = true}, {name = "awards", feed = true}, {name = "release-year", feed = true}, ]多语言场景下,每个语言(如[languages.fr])都可以有自己独立的 taxonomies 列表;如果你希望某个分类维度只在特定语言中存在,只需在对应语言的区块中声明它。仓库中的 test_site_i18n 就演示了多语言站点的整体结构。
仓库里的测试站点配置提供了一个贴近真实项目的示例:
taxonomies = [ {name = "categories", feed = true}, {name = "podcast_authors", feed = true}, ]其中feed = true表示每个 Term 都会生成对应的 Atom feed,方便订阅者按标签或分类维度订阅。
在内容中使用 Taxonomies
配置完成后,只需在内容文件的 front matter 中设置 taxonomies,Zola 在构建时会自动拾取:
+++ title = "Shape of water" date = 2019-08-15 # date of the post, not the movie [taxonomies] director=["Guillermo Del Toro"] genres=["Thriller","Drama"] awards=["Golden Globe", "Academy award", "BAFTA"] release-year = ["2017"] +++每个分类维度对应一个数组,数组中的每个字符串就是一个 Term。从源码看,front matter 中的taxonomies字段类型为HashMap<String, Vec<String>>(见 PageFrontMatter),即「维度名 → Term 列表」的映射。
关于 Term 值有两点需要注意:
- Term 不能为空字符串:解析 front matter 时,Zola 会遍历所有 Term 并校验非空,否则直接报错(见 page.rs 及对应测试
errors_on_empty_taxonomy_term)。 - TOML 与 YAML 均受支持:两种格式的 front matter 都能正确解析 taxonomies,仓库中的测试用例同时覆盖了两种写法(见 page.rs)。
输出路径规则
与 section 和 page 计算输出路径的方式类似,Zola 对 taxonomies 的输出路径遵循以下规则:
- Taxonomy 名称(维度名)永远不会被 slugify,直接按配置中的
name原样使用; - Taxonomy Term(如某个具体标签)在
slugify.taxonomies开启("on",默认值)时会被 slugify。
因此页面路径为:
$BASE_URL/$NAME/ (taxonomy) $BASE_URL/$NAME/$SLUG (taxonomy entry)大小写不敏感与 Term 合并
注意 Taxonomies 是大小写不敏感的:slug 相同的 Term 会被合并,因此内容中同时出现标签example和Example时,它们会归入同一个 taxonomy 页面。这一行为在源码中有明确实现:Taxonomy::new会对 Term 按 slug 排序后去重,去重时把相同 permalink 的 Term 的页面合并到一起(见 taxonomies.rs)。
仓库中的测试merges_terms_with_different_case专门验证了这一点:当内容中同时出现League of legends与League of Legends时,最终只生成一个 slug 为league-of-legends的 Term,并且两个页面都被合并其中(见 taxonomies.rs)。
通过 taxonomy_root 统一前缀
如果配置了taxonomy_root选项,所有 taxonomy 路径都会带上此前缀:
$BASE_URL/$TAXONOMY_ROOT/$NAME/ (taxonomy) $BASE_URL/$TAXONOMY_ROOT/$NAME/$SLUG (taxonomy entry)例如设置taxonomy_root = "blog"、taxonomy 名为tags、Term 为rust:
- Taxonomy 列表页:
$BASE_URL/blog/tags/ - Taxonomy Term 页:
$BASE_URL/blog/tags/rust/
从源码看,taxonomy_root是 Config 中的一个可选字段(默认None,见 mod.rs),路径拼接逻辑位于 get_taxonomy_path 与 get_taxonomy_term_path。仓库测试taxonomy_path_with_taxonomy_root精确断言了/blog/tags/与/blog/tags/rust/这两条路径(见 taxonomies.rs)。
多语言站点路径
在非默认语言中,路径会自动加上语言前缀。还是看源码实现:当lang不是默认语言时,路径形如/{lang}/{taxo_root}/{slug}/(配置了 taxonomy_root)或/{lang}/{slug}/(未配置),例如法语站点的 tags 列表页为/fr/tags/(见 mod.rs)。
slugify 策略与空 slug 报错
slugify.taxonomies支持三种策略(见 SlugifyStrategy):
| 策略 | 行为 |
|---|---|
on(默认) | 经典 slugification,例如"Rust & Web"→rust-web |
safe | 不做 slugify,仅移除对文件路径/URL 不安全的字符(如<>:"/\|?*及末尾的空格和点号) |
off | 完全不做任何处理,原样保留 |
在测试站点配置中可以看到完整的写法(test_site/config.toml):
[slugify] paths = "on" taxonomies = "on" anchors = "on"需要警惕的是:如果某个 Term 在 slugify 后变成空字符串(例如只包含特殊符号的 Term),Zola 会直接构建报错,提示你重命名该 Term(见 taxonomies.rs),对应测试为taxonomy_slug_is_empty_errors。
Term 内页面排序
Term 页面内的内容默认按日期倒序排列(Taxonomies 常用于博客场景),没有日期的页面会追加在末尾(见 taxonomies.rs)。
在模板中渲染 Taxonomies
Zola 为 taxonomies 提供了开箱即用的模板变量,通常需要两个模板文件:templates/tags/list.html(taxonomy 维度列表页)和templates/tags/single.html(单个 Term 页面)。
列表页:遍历 terms
在list.html中,terms变量包含该维度下所有 Term,每个 Term 暴露name、slug、pages(关联内容列表)与page_count等字段。参考测试站点模板:
{% for tag in terms %} {{ tag.name }} {{ tag.slug }} {{ tag.pages | length }} {% endfor %}单页:遍历 term.pages
在single.html中,term变量代表当前 Term。参考测试站点模板:
{% if not paginator %} Tag: {{ term.name }} {% for page in term.pages %} <article> <h3 class="post__title"><a href="{{ page.permalink | safe }}">{{ page.title | safe }}</a></h3> </article> {% endfor %} {% else %} Tag: {{ term.name }} {% for page in paginator.pages %} {{page.title|safe}} {% endfor %} Num pagers: {{ paginator.number_pagers }} Page size: {{ paginator.paginate_by }} Current index: {{ paginator.current_index }} First: {{ paginator.first | safe }} Last: {{ paginator.last | safe }} {% if paginator.previous %}has_prev{% endif%} {% if paginator.next %}has_next{% endif%} {% endif %}可见一旦 Term 页面启用了分页(配置了paginate_by),模板中即可通过paginator对象访问分页信息(number_pagers、paginate_by、current_index、first、last、previous、next)。
模板辅助函数
除了模板变量,Zola 还提供了三个与 taxonomies 相关的 Tera 函数(实现见 functions/taxonomy.rs):
get_taxonomy(kind="..."):返回整个分类维度的数据(含items列表),用于在任意页面展示分类导航。支持lang与required参数。get_taxonomy_term(kind="...", term="..."):返回指定 Term 的数据对象(含name、slug、permalink、pages)。即使 Term 名称经过了 slugify(如带重音符号的acción→accion),也可以通过 slug 或原名检索到(对应回归测试见 taxonomy.rs)。get_taxonomy_url(kind="...", term="..."):直接返回 Term 页面的 permalink 字符串,适合在导航或文章底部生成"相关标签"链接。旧版本使用name参数,现已废弃,统一改用term。
这三个函数都接受可选的lang参数(优先于模板上下文中的lang)与required参数(required = false时,找不到目标返回空值而不是报错,方便在非该分类维度的页面中安全调用)。
小结与验证方式
至此,一条完整的 Taxonomies 使用链路已经清晰:在配置文件的主区块声明维度与选项 → 在内容 front matter 的[taxonomies]中标注 Term → 构建时 Zola 自动收集、排序、去重合并并生成路径 → 通过list.html/single.html模板与辅助函数渲染。
如果你想在本地验证这些行为,可以直接运行仓库自带的测试:
- 路径生成测试:
taxonomy_path_with_taxonomy_root、taxonomy_path_without_taxonomy_root(见 taxonomies.rs); - 大小写合并测试:
merges_terms_with_different_case; - 空 slug 报错测试:
taxonomy_slug_is_empty_errors; - 模板函数测试:
can_get_taxonomy、can_get_taxonomy_url、can_get_taxonomy_term(见 functions/taxonomy.rs)。
同时,test_site 提供了完整的可运行示例(配置见 test_site/config.toml),包含categories与podcast_authors两个带 feed 的维度,以及对应的 tags 列表模板与tags 单页模板,是学习与实践 Taxonomies 的最佳起点。
【免费下载链接】zolaA fast static site generator in a single binary with everything built-in. https://www.getzola.org项目地址: https://gitcode.com/GitHub_Trending/zo/zola
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考