外观
3.1 订阅源生成
约 636 字
RSS分发
本页对应「三、操作步骤」的 3.1,从内容目录生成全站订阅源 rss.xml,完成字段填充、字符转义与格式校验,使阅读器可以正常订阅。返回上级:RSS 与邮件分发。
前置条件
- 文章源文件位于
/srv/axis/docs,每篇至少包含标题、日期、永久链接与摘要字段。 - 站点主域名为
example.com,文章链接可直接访问。 - 已安装
xmllint,用于校验生成的 XML;生成脚本可用node或bash。
操作步骤
- 确认内容目录结构与字段,先取一篇样例核对:
ls /srv/axis/docs | head -n 5
grep -m3 -E "^(title|date|permalink):" /srv/axis/docs/*.md | head -n 9- 用脚本抽取最近 20 篇,按发布时间倒序生成 RSS 2.0。以下为最小可用骨架,需按实际字段名替换:
node - <<'EOF'
const fs = require("fs");
const dir = "/srv/axis/docs";
const items = fs.readdirSync(dir).filter(f => f.endsWith(".md")).map(f => {
const s = fs.readFileSync(`${dir}/${f}`, "utf8");
const title = (s.match(/^title:\s*(.+)$/m) || [])[1] || f;
const date = (s.match(/^createTime:\s*(.+)$/m) || [])[1] || "";
const link = `https://example.com/notes/${f.replace(/\.md$/, "")}/`;
return { title, date, link };
});
const esc = t => t.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
const out = `<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"><channel>
<title>Axis Notes</title>
<link>https://example.com/</link>
<description>站点更新</description>
${items.map(i => `<item><title>${esc(i.title)}</title><link>${i.link}</link><pubDate>${i.date}</pubDate></item>`).join("\n")}
</channel></rss>`;
fs.writeFileSync("/srv/axis/public/rss.xml", out);
console.log("items:", items.length);
EOF- 校验 XML 合法性,确认没有未转义字符导致的解析失败:
xmllint --noout /srv/axis/public/rss.xml && echo "xml ok"
xmllint --xpath 'count(//item)' /srv/axis/public/rss.xml结果确认
xmllint --noout无输出,退出码为 0。count(//item)返回的数量与最近文章数一致,默认 20 条。- 用
curl -sS https://example.com/rss.xml获取线上文件,<link>与<pubDate>均有值。 - 在阅读器中订阅后能看到文章列表,标题与站点页面一致。
注意事项
- 摘要与标题必须转义
&、<、>,否则阅读器会直接报格式错误。 pubDate使用 RFC 822 格式,带时区偏移,缺时区会导致排序错乱。- 订阅源只输出域名下的公开链接,不要把带查询参数的临时地址写进去。
- 摘要长度固定,过长的摘要会让阅读器逐条截断,反而看不出重点。
- 生成脚本要能处理零文章与单文章两种边界情况,空数组时仍输出合法的
channel节点。 - 站点路径变更后同步更新订阅源中的链接前缀,旧链接失效会让订阅者看到大量 404。