我们为 RSS 轮询功能开发了一个小型的配套插件(discourse-rss-onebox):导入的博客文章会以文章 onebox 的形式渲染,并支持可选的 feed 摘要、YouTube 描述以及标题格式。由于存在三个功能缺口,我们不得不通过包装核心方法来实现,而不是使用已记录的钩子(hooks)。
-
Feed 表单中缺少插件出口(plugin outlet)。 rss-polling-feed-form.gjs#L287-L351 中没有
PluginOutlet,且更新契约(update contract)只接受一组固定的属性(update.rb#L9-L14)。插件无法为每个 feed 添加选项,因此我们的插件需要一个独立的管理页面。如果提供一个出口以及一种持久化额外字段的方式(例如 feed 自定义字段),就能解决这个问题。 -
Feed ID 从未传递到导入流程中。 轮询任务(poll job)知道
rss_feed_id,但TopicEmbed.import(poll_feed.rb#L110)和topic_embed_import_create_args修饰器(modifier)(topic_embed.rb#L108)从未接收到它。我们包装了轮询任务以捕获该 ID。如果将其作为选项传递下去,插件就可以针对每个 feed 执行操作。 -
更新路径上缺少钩子。 当 feed 项的内容发生变化时,
TopicEmbed.import会使用 feed 内容修订帖子(topic_embed.rb#L147-L152),从而绕过了创建修饰器所做的任何处理。如果博主编辑了一篇帖子,插件生成的主题格式会被静默地还原为普通的 feed 文本。如果在更新更改时提供一个镜像topic_embed_import_create_args的修饰器,就能弥补这一缺陷。
针对第 2 和第 3 点的变通方案是在 TopicEmbed.import 和轮询任务之前插入(prepend)代码。这种做法非常脆弱:main 分支后来为 TopicEmbed.import 添加了一个 truncate: 关键字参数,这破坏了任何镜像 2026.7 版本签名的包装器——我们不得不发布一个版本仅仅是为了传递该参数。如果提供已记录的钩子,就可以避免这类破坏性问题。