0x00 背景※
博客(Ankia-Theme / Trilium 分享)一直没有 RSS 订阅,读者无法用阅读器追踪更新。Trilium 没有内置 RSS 功能,但可以通过 type=code + mime=application/xml + #shareRaw 的组合,让分享页直接输出 XML 并返回正确的 Content-Type。
原理※
核心思路:利用 Trilium 的 ~runOnAttributeChange 脚本机制,在文章发布/取消发布时自动生成 RSS 2.0 XML,写入一个特殊配置的分享笔记。
关键要素※
| RSS 笔记 | nfd6wXh1gXOO — type=code, mime=application/xml, #shareRaw, #shareAlias=feed, 克隆到 _share |
| 更新脚本 | 0MQHOjMLocri — type=code, mime=application/javascript;env=backend |
| 触发机制 | 模板 efEPHPHiXGOg 上挂 ~runOnAttributeChange=0MQHOjMLocri,和 blogStateChange 并列 |
工作原理※
- 文章发布/取消发布 → 模板上的
~runOnAttributeChange触发 RSS 脚本 - 脚本通过
api.searchForNotes("#publish=true")获取所有已发布文章 - 遍历文章,用
note.getLabelValue()提取标题、分类、日期、摘要 - 生成 RSS 2.0 XML,按日期倒序排列,取最近 50 篇
- 通过
rssNote.setContent(xml)写入 RSS 笔记
为什么 shareRaw 可行※
之前担心 #shareRaw 仍返回 text/html。实测确认:当笔记 mime=application/xml 时,Trilium 返回的 Content-Type 就是 application/xml; charset=utf-8,且 shareRaw 模式下不包裹 HTML,原样输出。RSS 阅读器完全认可。
RSS 地址※
主地址(博客域名):https://www.tsaitang.com/feed
备用(Trilium 直连):https://tm.aketer.me/share/feed
为什么 tsaitang.com 不需要 /share/:Caddy 配置了 rewrite @notshare /share{path} 规则,所有不以 /share 开头的请求自动前缀 /share 再发给 Trilium。所以 /feed 等价于 /share/feed。tm.aketer.me 没有此规则,需带 /share/。
脚本代码※
脚本位于笔记 0MQHOjMLocri,核心逻辑:
if (api.originEntity.isDeleted) return;
if (api.originEntity.name !== "publish") return;
const notes = api.searchForNotes("#publish=true");
// 遍历 → 生成 RSS XML → setContent
维护备忘※
- 升级 Ankia-Theme 不受影响:脚本是独立笔记,不改 blogStateChange.js
- 模板上有两个 ~runOnAttributeChange:px0jPq1kJZFN(发布流程)和 0MQHOjMLocri(RSS 更新),两者独立触发
- atom:link 硬编码了 tsaitang.com:脚本中写死了
https://www.tsaitang.com/feed,不用变量拼接 - 属性重复问题:Trilium 笔记可能有同名 label 的多个值(继承+自身),脚本用
getLabelValue取第一个,正确 - 分享到 _share:RSS 笔记必须克隆到
_share虚拟目录下才能公开访问
0xFF 未完※
目前 RSS 只包含 blog 分类文章(笔记/生活/评论/记录),不含「说说」。如果需要加入说说,改脚本中的 CATS 数组即可。
atom:link 目前是硬编码,如果换域名需同步改脚本和 RSS 内容。