Trilium 博客 RSS 订阅实现

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 并列

工作原理

  1. 文章发布/取消发布 → 模板上的 ~runOnAttributeChange 触发 RSS 脚本
  2. 脚本通过 api.searchForNotes("#publish=true") 获取所有已发布文章
  3. 遍历文章,用 note.getLabelValue() 提取标题、分类、日期、摘要
  4. 生成 RSS 2.0 XML,按日期倒序排列,取最近 50 篇
  5. 通过 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 内容。

“您的支持是我持续分享的动力”

微信收款码
微信
支付宝收款码
支付宝

目录