报告:尝试替换 `show.rss.erb` 模板及遇到的问题

目标

  • 替换 discourse/app/views/topics/show.rss.erb 中的原始 Discourse 模板。
  • 将自定义模板放置在插件目录中:discourse-XXX/app/views/topics/show.rss.erb
  • 目标:让 RSS 页面加载插件模板而不是原始模板。

尝试的方法和结果

方法 1:直接将自定义模板放置在插件目录中

  • 操作: 将自定义的 show.rss.erb 放入 discourse-XXX/app/views/topics/
  • 结果: 仍在使用原始模板;RSS 页面未加载插件模板。

方法 2:使用 after_initializeprepend_view_path

after_initialize do
  class ::TopicsController
    prepend_view_path File.expand_path("../app/views", __dir__)
  end
end
  • 结果: 插件模板被忽略;RSS 页面继续使用原始模板。

方法 3:使用 after_initializeprepend_view_path 指向插件目录

after_initialize do
  class ::TopicsController
    prepend_view_path Rails.root.join("plugins/discourse-XXX-plugin-name/app/views")
  end
end
  • 结果: 插件模板仍未使用;RSS 页面继续渲染原始模板。

方法 4:覆盖 feed 方法并显式渲染插件模板

class ::TopicsController
  prepend_view_path Rails.root.join("plugins/discourse-XXX/app/views")

  alias_method :original_feed, :feed
  def feed
    raise Discourse::NotFound if !Post.exists?(topic_id: params[:topic_id])

    begin
      @topic_view = TopicView.new(params[:topic_id])
    rescue Discourse::NotLoggedIn
      raise Discourse::NotFound
    rescue Discourse::InvalidAccess => ex
      deleted =
        guardian.can_see_topic?(ex.obj, false) ||
        (!guardian.can_see_topic?(ex.obj) && ex.obj&.access_topic_via_group && ex.obj.deleted_at)

      raise Discourse::NotFound.new(
        nil,
        check_permalinks: deleted,
        original_path: ex.obj.relative_url,
      )
    end

    @first_post = @topic_view.posts.first

    discourse_expires_in 1.minute
    response.headers["X-Robots-Tag"] = "noindex, nofollow"

    render file: Rails.root.join("plugins/discourse-XXX/app/views/topics/show.rss.erb"), formats: [:rss]
  end
end
  • 结果: 插件模板似乎被调用了,但访问主题的 .rss 页面会导致“oops”错误。

我希望这份报告能清楚地总结所做的尝试和遇到的问题。我将非常感谢社区提供的任何见解、建议或解决方案,以成功替换 show.rss.erb 模板。提前感谢您的帮助!

  • 我认为您应该使用 __FILE__ 而不是 __dir__
  • 如果您在类体外部调用它,则应该是 self.prepend_view_path

所以我相信这会起作用

after_initialize do
  class ::TopicsController
    self.prepend_view_path File.expand_path("../app/views", __FILE__)
  end
end