Skip to Main Content
Zola 模板开发要点与 Markdown 语法速查Back to Top

Zola 模板开发要点与 Markdown 语法速查

14 minutes

Zola 模板的核心机制(结合 Zola 官方文档 与本站实践),以及参考 daudix.one/content 整理的 Markdown / Shortcode 写法示例。

警告:zola.toml若启用新功能, 记得在该文档中 更新说明 使用方法


一、Zola 模板:目录与优先级

Zola 的模板引擎是 Tera(语法接近 Jinja2 / Liquid)。站点根目录结构:

.
├── config.toml          # 全局配置
├── content/             # Markdown 内容(按 section 组织)
├── templates/           # 站点级模板(优先级高于 theme)
├── static/              # 原样拷贝的静态资源
├── sass/                # 可选,编译为 CSS
└── themes/ametrine/     # 主题(可被 templates/ 同名文件覆盖)

覆盖规则templates/ 下与主题同路径的文件会完全替换主题模板。例如:

{# templates/article.html — 只改文章页,不动 theme #}
{%% extends "ametrine/templates/article.html" %%}

{%% block content %%}
{{ super() }}
{# 追加滚动条、热力图等 #}
{%% endblock %%}

原则:不改 themes/ 内文件,在 templates/ 里 extends + block 扩展。


二、模板类型与 front matter 绑定

模板文件用途典型绑定方式
base.html全站骨架(<html>、header、sidebar、footer)被其他模板 extends
section.htmlSection 索引页(_index.mdsection 默认模板
page.html独立 Pagepage 默认模板
article.html单篇文章page_template = "article.html"
article_list.html文章列表 + 分页template = "article_list.html"
自定义如 archive.html归档页等特殊布局_index.mdtemplate = "archive.html"

Section 的 _index.md 示例(参考 daudix 的 blog/_index.md):

+++
title = "效率-工作流"
sort_by = "date"
template = "article_list.html"      # 列表页模板
page_template = "article.html"      # 该 section 下每篇文章的模板
paginate_by = 10
generate_feeds = true
[extra]
no_header = true                    # 传给模板,控制是否渲染 h1
+++

三、Tera 核心语法

3.1 继承与块(extends / block / super)

{%% extends "ametrine/templates/base.html" %%}

{%% block content %%}
  <main>&#123;&#123; section.content | safe &#125;&#125;</main>
{%% endblock content %%}

在子模板中调用父块内容:super() 过滤器(写作 &#123;&#123; super() &#125;&#125;)(本站 article.html 即此模式)。

3.2 引入片段(include / import)

{%% include "partials/heatmap_component.html" %%}

{%% import "macros/macros.html" as macros %%}
&#123;&#123; macros::translate(key="skip_to_content", default="Skip", language_strings=language_strings) &#125;&#125;

3.3 常用变量(构建时注入)

变量含义
configzola.toml 全文,含 config.extra.*
page当前页面(title、date、content、permalink、taxonomies…)
section当前 section(pages 列表、title…)
lang当前语言
current_url当前页面 URL

3.4 常用函数与过滤器

{# 跨 section 拉取文章 — archive.html 中的用法 #}
{%% set sec = get_section(path="03Share_blog/_index.md") %%}
{%% set posts = sec.pages | sort(attribute="date") | reverse %%}

{# 加载外部数据 #}
{%% set strings = load_data(path="i18n/en.toml") %%}

{# 过滤器链 #}
&#123;&#123; page.date | date(format="%Y-%m-%d") &#125;&#125;
&#123;&#123; heat_data | json_encode() | safe &#125;&#125;
{%% for year, posts in all_posts | group_by(attribute="year") %%}

3.5 图片处理(build 时)

主题 base.html 中常见写法:

{%% set blurnail = resize_image(path=page.colocated_path ~ banner, width=4, height=2, op="fill", format="webp") %%}

page.colocated_path 指向与 index.md 同目录,便于 co-located 资源。


四、Shortcode(短代码)

放在 templates/shortcodes/*.html,Markdown 中写作:

{%% shortcode_name(param="value") %%}
内容
{%% end %%}

或自闭合:{%% icon(name="github") %%}

在 Markdown 正文中展示 shortcode 字面量时,用 {%% / %%} 转义,避免被 Zola 当作 shortcode 执行。

查找顺序:站点 templates/shortcodes/ → 主题 themes/ametrine/templates/shortcodes/


五、Markdown 语法示例

以下示例整理自 daudix.one 的常见写法,并标注 ametrine 支持情况。

5.1 Front matter(TOML)

+++
title = "文章标题"
description = "摘要,用于列表卡片与 SEO"
date = 2026-06-22
updated = 2026-06-22
draft = true                        # 草稿,需 zola build --drafts
[taxonomies]
tags = ["Zola", "Devlog"]
categories = ["Featured"]
[extra]
toc = true                          # 目录
accent_color = ["hsl(254 44% 55%)", "hsl(290 20% 71%)"]  # 浅色/深色强调色
banner = "banner.webp"              # 与 index.md 同目录的横幅图
[extra.fediverse]
host = "vmst.io"
user = "username"
id = "113295812044964246"           # 启用 Fediverse 评论
+++

section级(_index.md)

+++
title = "CMake 4.0 技术细节整理 专栏"
description = "My writings, I suppose."
sort_by = "date"
template = "article_list.html"
page_template = "article.html"
paginate_by = 10
generate_feeds = true             
[extra]
scripts = ["analytic/umami.js"]  # 启用访客来源统计
no_header = true

+++

page级(index.md)


+++
title = "Mac 本地网络 配置优化方案"
description = "提升网络访问性能,减少硬件性能损耗"
updated = 2026-06-20          # 最新更新时间, 若 section的_index.md 中设置以时间排序,以这个为准
date = 2026-06-20              # 👈 确保这里有规范的日期
[taxonomies]
tags = ["zsh","Mac" ]  # 标签
categories = ["Hot"]  # 分类
[extra]
accent_color = ["hsl(26.511627 25% 34%)", "hsl(26.75676 31% 53%)"]
+++

5.2 内部链接

Zola 专用 @/ 前缀,构建时解析为正确 permalink:

详见 [网站重写 Devlog](@/blog/2023-08-13-site-and-blog-devlog/index.md)

脚注式引用:[为什么叫这个名字?](@/03Share_blog/2025-10-04-Zola-build-deploy-circle/index.md)

5.2.0 页间跨页跳转

``TODO` 待补充

5.2.1 页内块跳转

``TODO` 待补充

5.3 标题与目录

## 二级标题        → 自动生成锚点
### 三级标题

[extra] toc = true  → 文章顶部自动生成目录

5.4 文本样式

**粗体**  *斜体*  ~~删除线~~  `行内代码`

> 引用块
> 可以多行

上标脚注引用[^1],文末定义脚注内容。

[^1]: [Dependency hell](https://en.wikipedia.org/wiki/Dependency_hell)

5.5 术语块(daudix 风格)

 

**SSG:** Static Site Generator,将 Markdown 转为静态 HTML 的构建工具。
 

5.6 表格

| 页面 | 旧仓库 | 新仓库 |
| ---- | ------ | ------ |
| Home | pages  | website |
| Blog | blog-source | website |

5.7 代码块

支持语法高亮(本站 zola.toml 配置 monokai-pro 主题):

TOML 配置示例:

[markdown]
smart_punctuation = true
github_alerts = true

HTML 模板示例(Tera 语法,写作时用 {%% / %%} 转义可在正文中展示字面量):

{%% extends "base.html" %%}
{%% block content %%}&#123;&#123; page.content | safe &#125;&#125;{%% endblock %%}

Shell 命令:

zola build --force
zola serve --drafts

5.8 GitHub Alerts(github_alerts = true 时)

> [!NOTE]
> 这是提示框,无需手写 shortcode。

> [!WARNING]
> 警告信息。

> [!TIP]
> 小技巧。

等价的 shortcode 写法(ametrine alert.html):

{%% alert(title="Note", icon="info", color="note") %%}
自定义图标与颜色的提示块。
{%% end %%}

5.9 图片

普通 Markdown 图片(与 index.md 同目录放 photo.png):

![Obsidian 附件目录配置](obsidian-attachments.png)

daudix 技巧:URL 锚点控制样式(无需 Kramdown 的 {: .class}):

![透明背景 PNG](context-menu.png#transparent)
![像素风渲染](sprite.png#pixels)
![无 hover 效果](logo.png#transparent#no-hover)

对应 SCSS 选择器示例:

img[src*="#transparent"] { background: transparent; }
img[src*="#pixels"]       { image-rendering: pixelated; }

Shortcode 图片(更多参数):

{%% image(url="banner.webp", alt="横幅", full=true, drop_shadow=true) %%}

5.10 ASCII / CRT 艺术字

Section 首页与 daudix blog 首页常用的 crt shortcode:

{%% crt(label="ASCII 插画:左侧卡车,中间房屋,右侧火箭") %%}
         *                 *
  *              _________##
                @\\\\\\\\\##
 *             @@@\\\\\\\\##\
{%% end %%}

渲染为 .crt 样式的 <pre>,带 CRT 扫描线效果。

5.11 嵌入媒体

YouTube(隐私增强域名,需 CSP 允许 youtube-nocookie.com):

{%% youtube(id="dQw4w9WgXcQ") %%}
{%% youtube(id="abc123", start=30, autoplay=false) %%}

Vimeo / 本地视频 / 音频

{%% vimeo(id="123456789") %%}

{%% video(url="clip.mp4", controls=true, loop=true, muted=true) %%}

{%% audio(url="podcast.mp3", name="播客片段") %%}

5.12 图标

{%% icon(name="github") %%}
{%% icon(name="terminal", inline=true) %%}

图标来自 Phosphor SVG,主题 icons/phosphor/ 目录。

5.13 Emoji shortcode

render_emoji = false 时,可用 shortcode 插入:

{%% emoji(name="🦀") %%}

5.14 本站自定义 shortcode

templates/shortcodes/ 下还有:

Shortcode用途
badges徽章展示
polaroid宝丽来相框图片
window窗口 UI 框
masonry瀑布流图片墙
todoTODO 列表
now_playing正在播放
online在线状态

用法均为 {%% name(参数) %%}...{%% end %%},具体参数见对应 html 文件。


六、模板开发注意点清单

  1. 不要改 theme:在 templates/ 覆盖或 extends。
  2. safe 过滤器page.content| markdown | safe 输出已解析 HTML;纯文本勿加 safe。
  3. Section 路径get_section(path="03Share_blog/_index.md") 路径相对 content/
  4. 全局变量{%% set_global x = ... %%} 在 loop 内累加时使用。
  5. CSP:嵌入 iframe / 外部脚本需在 zola.toml[extra.csp] 声明域名。
  6. 静态资源:JS/CSS 放 static/,引用 /js/xxx.js;Sass 放 sass/ 由 Zola 编译。
  7. Co-located 资源:图片与 index.md 同目录,构建后 permalink 同路径,便于搬运整文件夹。
  8. 分页paginate_by = 10 + 模板中使用 section.pages 与 paginator partial。
  9. 多语言content/ 下按语言分子目录,配合 i18n/*.toml
  10. 调试zola build --force 强制重建;zola serve --open 热重载预览。

七、本站实践对照

功能实现位置
文章页扩展(热力图、滚动条、音乐)templates/article.html extends + include partials
归档页 + 年份热力图templates/archive.html + heatmap_component.html
文章页音乐播放器partials/music_player.html + static/js/music-player.js
自定义列表模板templates/article_list.html / nanolog_list.html
全局配置zola.tomlconfig.extra.*
主题变量(颜色)ametrine --bg-muted-1--accent-color 等 CSS 变量


八、构建流程

8.1 音乐播放器:如何在新博客中启用

全站开关(zola.toml,已配置可跳过)

[extra.music_player]
enabled = true
base_url = "/music"   # 对应 static/music/ → public/music/

单篇文章 front matter

[extra.music_player]
enabled = true
tracks = [
  { file = "歌手-歌名" },
  { file = "周杰伦-青花瓷" },
]

资源文件命名(放在 static/music/

文件说明
歌手-歌名.mp3.flac音频;优先使用 MP3(体积更小、seek 更稳)
歌手-歌名.lrc歌词;UTF-8 或 GB18030

file 字段不带扩展名,播放器自动探测 .mp3.flac

行为摘要


8.2 构建与预览命令对照

场景命令说明进度条能否立刻拖
日常预览zola buildzola serve改样式、普通文章足够首次拖可能需等整首下载(Blob 兜底);之后正常
加密文章开发./dev.shencrypt-content.mjs,再 zola serve同上
正式部署 / CI./build-site.sh加密 → build → post-build → kanban 校验线上 GitHub Pages 支持 Range,可直接拖(需 static/music/ 已部署)
本地想立刻拖见下方两行可选;不改日常习惯立刻可拖,与线上一致

日常预览与加密开发(标准流程,未改):

# 普通文章
zola build
zola serve

# 新增/修改加密文章
./dev.sh

正式部署:

./build-site.sh
# CI 同:.github/workflows/deploy_pages.yml → ./build-site.sh --output-dir ../public_html

本地立刻验证进度条 seek(可选):

zola build --base-url http://127.0.0.1:1111/
node scripts/serve-with-ranges.mjs --no-watch -p 1111

然后访问 http://127.0.0.1:1111/。说明:

其他常用命令:

zola build --force   # 清空 output 后重建
zola check           # 检查链接,不输出站点

设计细节与根因分析见 Nanolog · 热力图与音乐播放器


8.3 原构建命令速查

./build-site.sh  # 可选;若存在新增加密博客则必选
zola build --force
zola serve
zola check

九、部署与发布

部署源码 参考 .github/workflows/deploy.yml

十、Zola.toml 配置 节点作用解读

全局(zola.toml)

title = "Rocky‘s Blog"  
base_url = "https://suchaharcan.github.io/"
description = "月更 技术博客 CXX优先"

theme = "ametrine"

compile_sass = true
minify_html = true
feed_filenames = ["atom.xml", "rss.xml"]            # 生成的 RSS/Atom 订阅文件
build_search_index = true                            # 生成搜索索引
author = "Suchaharcan" 


taxonomies = [
  { name = "tags", feed = true, paginate_by = 10 },
  { name = "categories", feed = true },
]                                               # 分类和标签的配置

[markdown]
render_emoji = false
smart_punctuation = true
lazy_async_image = false
bottom_footnotes = true             # 脚注显示在底部
external_links_class = "external"
github_alerts = true            # 显示 GitHub 警告

[markdown.highlighting]
style = "class"
light_theme = "monokai-pro-light"
dark_theme = "monokai-pro"
extra_themes = [
  "themes/ametrine/giallo/themes/monokai-pro-light.json",
  "themes/ametrine/giallo/themes/monokai-pro.json",
]

[extra]
# Put all your custom variables here
# 全站 Umami:static/analytic/umami.js(覆盖首页 / 文章 / 标签 / 404 等所有页面)
scripts = ["analytic/umami.js"]

feed_sections = [

  { name = "Nanolog", path = "@/nanolog/_index.md" },
  { name = "Blog", path = "@/01Write_blog/_index.md" },
]                                 # 手动指定 哪些导航栏中的 RSS 可订阅项 sections 

accent_color = ["hsl(270 13% 48%)", "hsl(290 20% 71%)"]
# home_url = "@/home/index.md"
issues_url = "https://github.com/SuchaharCan/SuchaharCan.github.io/issues/new"            # 弃用 
source_url = "https://codeberg.org/SuzhaharCan/SuzhaharCan.codeberg.page"            # 网站源码在Codeberg ,可跳转直接在线修改博客, 在 kanban/ nanolog/ 中使用 
replog_url = "https://github.com/SuchaharCan/SuchaharCan.github.io/actions/workflows/deploy_pages.yml"            # 网站部署在 github.io, 可跳转点击 触发重新部署 。
copy_button = true
show_reading_time = true

show_backlinks = true
date_format = "%d %B %Y"
date_format_long = "%d %B %Y, %R (%Z)"
date_locale = "en_IE"                    # zola 暂不支持中文, 默认 英文
timezone = "Asia/Shanghai"               # 时区, HTML/JS 业务逻辑判断 使用


show_comments_qr = false  #评论二维码, 暂时禁用, 我有 社交账号,但我暂无 海外运营想法 禁用,若文章有价值, 我会直接 分享到HackerNews 上


csp = [
  { directive = "font-src", domains = [
    "'self'",
  ] },
]          # 内容安全策略,启用,限制外部脚本注入,提高网站 安全性, 若 后续功能开发的模块需要 JS脚本,此处需要 同步更新

[extra.music_player]
enabled = true
base_url = "/music"   # 音乐资源:static/music/ → /music/

单篇文章启用播放器:在文章 front matter 增加 [extra.music_player],见 §8.1

手动指定 文章分类, 用于 文章列表页面 的 分类显示 大类划分 : 归档, 有价值, 热门



[[extra.categories]]
name = "Tracking"
description = "Posts that need to be continuously updated."
color = "green"
icon = "fire"

构建脚本说明:dev.shbuild-site.sh

本站有两条常用入口脚本,分别对应本地开发预览正式构建。二者都会在 Zola 构建前同步加密文章密文,但后续步骤不同。


一览

脚本用途输出典型场景
./dev.sh本地开发 + 热重载预览不强调完整 public/ 产物改文章、改样式、调试加密页
./build-site.sh正式静态站点构建public/(或 --output-dir 指定目录)部署前、CI、需要完整校验

dev.sh — 本地开发

作用

在本地启动 Zola 开发服务器zola serve),保存文件后自动重建并刷新预览。

执行步骤

① node scripts/encrypt-content.mjs   # 同步加密文章密文
② zola serve [你传入的参数]          # 本地预览(默认 http://127.0.0.1:1111)

源码

node scripts/encrypt-content.mjs
exec zola serve "$@"

何时使用

不会做的事

常用示例

./dev.sh                    # 默认端口 1111
./dev.sh --open             # 构建后自动打开浏览器
./dev.sh -p 3000            # 指定端口

说明


build-site.sh — 正式构建

作用

生成可部署的静态站点目录,并完成加密相关的构建后处理看板校验。CI(.github/workflows/deploy_pages.yml)调用的是本脚本。

执行步骤

① node scripts/encrypt-content.mjs      # 全量同步加密密文
② zola build [可选参数]                  # 输出静态 HTML 到 public/
③ node scripts/post-build.mjs           # 从 RSS/Atom、搜索索引移除加密文章
④ node scripts/verify-kanban-build.mjs  # 校验 kanban 周页是否均已生成

各子步骤职责

步骤脚本说明
构建前encrypt-content.mjs扫描 content/,对 encrypt = true 的文章重加密;删除已取消加密的多余 JSON
构建zola buildZola 原生编译:Markdown → HTML,拷贝 static/public/
构建后post-build.mjs加密页不出现在订阅源与站内搜索索引中
构建后verify-kanban-build.mjs确保 content/kanban/YYYY-MM-DD.md 在输出目录均有对应页面

何时使用

常用示例

./build-site.sh
./build-site.sh --output-dir ../public_html   # CI 用法;并 export ZOLA_OUTPUT_DIR 供后置脚本

参数


对比:何时用哪个

需求推荐命令
本地边改边看./dev.shzola serve
改了加密文章并要本地解密预览./dev.sh
部署前完整构建./build-site.sh
只改样式、不涉及加密zola build && zola serve 即可
本地立刻验证音乐进度条 seekzola build --base-url http://127.0.0.1:1111/node scripts/serve-with-ranges.mjs --no-watch -p 1111(可选,见模板指南 §8.2)

与 CI 的关系

GitHub Actions 工作流 不调用 dev.sh,部署步骤为:

./build-site.sh --output-dir ../public_html

与本地正式构建一致,无需单独改 workflow。


相关文件

路径说明
scripts/encrypt-content.mjs构建前加密同步
scripts/post-build.mjs构建后 feed / 搜索过滤
scripts/verify-kanban-build.mjs看板产物校验
scripts/encryption-lib.mjs加密与 feed 处理共享库
scripts/serve-with-ranges.mjs可选:带 byte-range 的本地静态服务(非 dev.sh 默认流程)

更细的加密架构与命令对照见:

参考


本文即按上述规范编写:toc = true 启用目录,accent_color 设置页面强调色,内部链接使用 @/ 语法。

Read Also