Discourse 转 Markdown 插件

discourse-to-markdown 是一个新插件,当客户端发送 Accept: text/markdown 或在任何内容 URL 后附加 .md 时,它会以 Markdown 格式返回论坛内容。

我们已在自己的论坛 https://discourse.roots.io 上运行该插件:

curl -H "Accept: text/markdown" https://discourse.roots.io/latest
curl https://discourse.roots.io/t/serve-your-wordpress-posts-as-markdown/30321.md

将 HTML 输入大语言模型(LLM)成本高昂,而提供仅包含内容的 Markdown 通常可将 token 使用量减少 3–5 倍。这意味着更低的 API 调用成本、更快的响应速度,以及为模型推理腾出更多的上下文窗口空间。如需了解更详细的介绍以及针对任意站点的就绪性检查,请访问 https://acceptmarkdown.com

客户端如何请求 Markdown

三种入口:

  1. Accept: text/markdown 请求头(最适合 LLM)
  2. .md URL 后缀
  3. 发现机制(每个 HTML 响应通过 Link: <...>; rel="alternate"; type="text/markdown" 请求头以及 <head> 中的 <link rel="alternate"> 标签来宣传其对应的 Markdown 版本;RSS 订阅源也包含指向 Markdown 等效版本的 <atom:link>

支持的路由

路由 HTML Markdown
主题 /t/:slug/:id /t/:slug/:id.md
单条帖子 /t/:slug/:id/:post_number /t/:slug/:id/:post_number.md
分类 /c/:slug/:id /c/:slug/:id.md
标签 /tag/:tag /tag/:tag.md
最新 /latest /latest.md
热门排行 /top /top.md
热门话题 /hot /hot.md
用户动态 /u/:username/activity /u/:username/activity.md

安装

将插件添加到您的 app.yml

hooks:
  after_code:
    - exec:
        cd: $home/plugins
        cmd:
          - git clone https://github.com/roots/discourse-to-markdown.git

重新构建容器:

cd /var/discourse
./launcher rebuild app

然后在 管理 → 设置 → 插件 → Markdown 输出 中启用它。

转换说明

该插件转换的是 Discourse 的 cooked HTML(即读者看到的渲染后内容,包含已展开的 oneboxes、已链接的提及和已归属的引用),而非 raw 内容。这保留了读者实际看到的内容,并确保输出可在任何兼容 GFM 的渲染器中使用。Discourse 特有的结构(引用、oneboxes、details、提及、话题标签、表情符号、灯箱、投票)会在转换前被合理重写。

转换后的 Markdown 会基于 post.idpost.updated_at 作为键缓存在 Redis 中,编辑操作会自动使缓存失效。

设置

设置项 默认值 用途
discourse_to_markdown_enabled false 插件的主开关
discourse_to_markdown_md_urls_enabled true 接受 .md URL 后缀作为 HTML 路由的对应版本
discourse_to_markdown_strict_accept false 当客户端的 Accept 请求头同时排除 text/htmltext/markdown 时返回 406 Not Acceptable
discourse_to_markdown_emit_vary true 在 Markdown 和 406 响应中发出 Vary: Accept,防止缓存交叉提供不同表示形式
discourse_to_markdown_include_post_metadata true 在 Markdown 表示中包含 URL、分类、标签、作者和时间戳

资源

9 个赞

这太棒了,感谢发布!

这也是一种非常酷的方法。它生成的 Markdown 比原始输出更丰富,因为它利用了 Discourse 的 cooking 基础设施。

2 个赞

天哪,这正是我一直在找的,时机太棒了!我们经常使用 API 或 MCP,但原始内容中缺少已解析的图片 URL 一直让我们很头疼。

感谢你们的付出!

编辑:这个功能是否也能与 Discourse MCP 一起使用呢?

1 个赞

很高兴它很有用!

Discourse MCP 可以将内容协商作为可选路径添加。它不需要依赖此插件,而是可以从规范的帖子/主题 URL 请求 Accept: text/markdown,如果站点不支持 Markdown,则回退到当前的 JSON API 行为。

此插件只是目前 Discourse 站点满足该请求的一种方式。如果没有此插件或 Discourse 核心中的等效支持,仅凭 Accept 头无法改变 JSON API 的输出。

因此,理想的 MCP 集成方式可能是:首先尝试对内容 URL 使用 text/markdown,然后回退到 /t/:id.json?include_raw=true

1 个赞

真巧,你这么说,因为 Claude 正是用这种方式解决的……