第4章:Templater 模板自动化
本章结构:先理解 Templater 是什么、能做什么 → 再新建 Books 模板并导入第一本书。
前提:第1章:环境 已完成,库里有Tools/Templater/文件夹。
预计时间:概念 15 分钟 + 实操 45 分钟
1. Templater 是什么
Obsidian 自带「模板」插件只能做简单文本替换(如插入日期)。
Templater(社区插件 templater-obsidian)是它的超集:
- 在笔记里写模板文件(放在指定文件夹)
- 插入模板时执行 JavaScript
- 弹窗让用户输入、选择
- 自动改 frontmatter、移动文件、调用 Obsidian API
一句话:把「每次新建笔记都要手填的重复劳动」变成一键模板 + 可选脚本。
2. 核心功能
| 功能 | 说明 |
|---|---|
| 插入模板 | 命令面板 / 快捷键 / 新文件触发 |
<% tp.date.now() %> |
动态日期、时间 |
<%* ... %> |
运行 JS 脚本块 |
tp.system.prompt |
单行输入框 |
tp.system.multi_suggester |
多选列表(本教程 Books 模板用) |
tp.file |
当前文件标题、路径、光标 |
processFrontMatter |
安全修改 YAML |
on_all_templates_executed |
等模板跑完再改 frontmatter(避免被覆盖) |
{{占位符}} |
静态占位,常由 Douban 等插件在导入前替换 |
3. 与 Douban、Dataview 的分工
flowchart LR DB["Douban 填 title、isbn 等占位符"] --> TP["Templater Books.md"] TP --> FM["统一 frontmatter"] FM --> MD["Books/书名.md"] FM --> DV["Dataview 查询"]
- Douban:从豆瓣拉元数据,替换
{{title}}等 - Templater:决定笔记长什么样、弹窗选标签、写
dg-publish等 - Dataview:只读 frontmatter,不写入
在「我的书架」里:Douban → Templater → 得到结构统一的 Books/*.md。
4. 理解三种语法层次
初看 Templater 的模板文件可能会有点晕——里面混着 {{}}、<% %>、<%* %> 三种标记。它们虽然长得像,但执行的时机和角色完全不同。
| 语法 | 执行时机 | 谁在控制 | 典型用途 |
|---|---|---|---|
{{title}} |
Douban(或其他外部插件)导入时替换 | Douban,不是 Templater | 书名、ISBN、作者名——这些值来自豆瓣 API |
<% tp.date.now("YYYY-MM-DD") %> |
插入模板那一刻执行 | Templater | 填入当天日期、文件名等动态值 |
<%* ... %> |
插入模板那一刻执行,可写完整 JS | Templater | 弹窗选标签、修改 frontmatter、调用文件 API |
一个容易混淆的地方:<% tp.xxx %> 和 <%* ... %> 的区别在于带星号 * 的版本可以包含 await(等待异步操作完成)和更复杂的控制流。简单取值用 <% %>,写逻辑用 <%* %>。
另一个重要规则:{{}} 不是 Templater 的功能——它是 Douban 这类插件定义的占位符约定。如果你的笔记没有经过 Douban 导入就直接插入 Books 模板,{{title}} 会原样保留在笔记里,不会被替换。
5. 跟着做:基础设置
设置 → Templater- Template folder location →
Tools/Templater - 建议开启:
- Trigger Templater on new file creation(按需)
- Automatic jump to cursor(插入模板后光标跳到
<% tp.file.cursor() %>位置,若模板里有)
- 关闭设置
验证:Ctrl+P → Templater: Open Insert Template modal → 完成第 7 节后应能看到 Books。
6. 跟着做:新建 Books 模板
- 在
Tools/Templater/右键 → New note - 命名为
Books.md - 把下面 整段 粘贴进去并保存
若你已有同名文件,直接打开对照修改即可。
2.4.1 Frontmatter:Douban 占位符
---
addDate: {{currentDate}}
title: "{{title}}"
author: "{{author}}"
publishDate: {{datePublished}}
pages: {{totalPage}}
ISBN: "{{isbn}}"
cover: assets/{{isbn}}.jpg
rating: {{score}}
myRating:
publisher: "{{publisher}}"
tags:
- 待读
---
Douban 导入时会替换 {{title}}、{{isbn}} 等。tags 里先写默认 待读,后面脚本会覆盖。
2.4.2 脚本块:弹窗选标签 + 写 Digital Garden 字段
<%*
const tagOptions = ["文学", "哲学", "心理学", "小说", "非虚构", "传记", "历史", "科幻", "散文", "灵修", "佛学", "待读"];
const picked = await tp.system.multi_suggester(tagOptions, tagOptions, false, "选择书籍标签(可多选,Esc 保留默认)");
const tags = picked && picked.length ? picked : ["待读"];
const file = tp.config.target_file;
tp.hooks.on_all_templates_executed(async function () {
await tp.app.fileManager.processFrontMatter(file, function (fm) {
fm["dg-publish"] = true;
fm["dg-hide"] = true;
fm["dg-show-toc"] = true;
fm.tags = tags;
var isbn = String(fm.ISBN || "").replace(/[^0-9X]/gi, "");
if (isbn) {
fm["dg-permalink"] = "books/" + isbn;
}
});
});
%>
逐行说明
| 代码 | 作用 |
|---|---|
multi_suggester |
弹出多选列表;Esc 不选则用 ["待读"] |
tp.config.target_file |
当前正在创建的笔记文件 |
on_all_templates_executed |
等模板全部执行完再改 frontmatter,避免被覆盖 |
processFrontMatter |
安全修改 YAML,不用手写字符串拼接 |
dg-permalink |
将来 Digital Garden 发布用的 URL(见 第7章:扩展) |
2.4.3 正文与封面嵌入
!cover
# 📖 <% tp.file.title %>
> **一句话总结**:
!cover:Obsidian 内嵌本地封面(Douban 下载到assets/)<% tp.file.title %>:用当前文件标题作一级标题
验证:Ctrl+P → Templater: Open Insert Template modal → 列表里出现 Books。
8. 跟着做:Douban → Books(导入第一本书)
前提:桌面端;Douban 已在 设置 → Douban 中登录;Books.md 已按 2.4 节创建。
步骤
Ctrl+P→ 输入Douban或豆瓣- 选择 搜索并导入 类命令(名称以你安装的 Douban 版本为准)
- 搜索书名,例如:
白色绵羊里的黑色绵羊 - 选择 书籍 类型 → 确认导入
- 在模板选择处选
Books - 弹出标签选择器 → 选「文学」等 → 确认
- 等待 Douban 下载封面(若开启保存附件)
验证
-
新建文件位于
Books/下 -
frontmatter 含
ISBN、tags(不止默认待读)、dg-publish: true -
正文能显示封面;
assets/下有对应ISBN.jpg -
这是你 第一本 入库的书;路径类似
Books/白色绵羊里的黑色绵羊.md
2.6 跟着做:手动插入模板(不经过 Douban)
用于测试模板是否正常工作:
- 在
Books/新建笔记测试模板.md Ctrl+P→Templater: Open Insert Template modal- 选 Books
- 观察:
{{title}}等未被 Douban 替换的占位符会原样保留——这是预期行为
2.7 其他模板(可选)
下面两个模板本教程不强制要求创建;等你熟悉 Templater 后,可以按需加到 Tools/Templater/ 里:
Daily.md — 日记(可选)
- 用
<% tp.date.now("YYYY-MM-DD") %>写日期 - 含
request()拉天气(依赖外网;移动端可能慢) - 适合配合 Calendar 插件跳转
MeetingMinutes.md — 会议纪要(可选)
<% await tp.system.prompt("关联项目名称") %>
演示 tp.system.prompt 单行输入,可仿照做「读书笔记」模板。
2.8 练习:新建 ReadingNotes 模板
目标:不用 Douban,手动建读书笔记。
跟着做
- 新建
Tools/Templater/ReadingNotes.md,写入:
---
date: <% tp.date.now("YYYY-MM-DD") %>
book: <% await tp.system.prompt("书名") %>
rating:
tags:
- 读书笔记
---
# 📓 <% await tp.system.prompt("书名") %>
## 摘要
## 金句
## 我的评价
- 在
Books/新建笔记 → 插入 ReadingNotes 模板 - 按提示输入书名
验证:frontmatter 含 book、date;正文有三个二级标题。
2.9 练习:给 Books 增加一个自定义标签
- 打开
Tools/Templater/Books.md - 在
tagOptions数组末尾加一项,例如"经济" - 保存
- 再导入一本书,确认弹窗里出现「经济」
2.10 常见坑
| 现象 | 原因 | 处理 |
|---|---|---|
tags 始终是 [待读],弹窗选的标签没写进去 |
模板里的脚本块没用 on_all_templates_executed 包裹 |
对照模板里的脚本,确保 processFrontMatter 是在 on_all_templates_executed 回调里调用的 |
| 安卓上模板脚本弹窗报错 | 移动端 Obsidian API 不完整,不支持某些 Templater 功能 | 导入书籍、创建模板这些操作在桌面完成,手机只负责阅读 |
{{isbn}} 原样留在正文,没被替换成数字 |
没有走 Douban 导入流程,手动插入模板时 {{}} 不会被替换 |
{{}} 占位符只有 Douban 这类外部插件能替换;手动插入请用 Templater 自己的 <% %> 语法 |
| 封面图片不显示 | 封面文件没下载到 assets/ 或者 cover: 字段里的路径不对 |
Douban 设置里开启「保存附件」;检查生成的 cover: assets/xxx.jpg 路径是否和实际文件一致 |
2.11 与下一篇的衔接
Templater 负责 写入 统一 frontmatter → 第5章:Dataview 负责 读取 并生成书单。
本章练习 checklist
| ← 上一章 | 蒸馏术 主页 | 下一章 → |
|---|---|---|
| 第3章:Claudian | 第5章:Dataview |