【问题标题】:How can I intercept rails's template rendering如何拦截rails的模板渲染
【发布时间】:2011-08-28 15:48:55
【问题描述】:

我有一个为多个网站提供服务的应用程序。 与 Stack Exchange 类似,这几个网站的行为非常相似。

给定以下视图目录结构:

views/
  shared/users/index.html.erb
  app1/users/index.html.erb
  app2/users/

如何在 Rails 中重写默认的模板渲染,以便

  • 当 App1 的 UsersController#index 被调用时,它会渲染 app1/users/index.html.erb
  • 当 App2 的 UsersController#index 被调用时,它意识到没有 index.html.erb 模板,因此在引发缺少模板错误之前检查 shared/users/index.html.erb

提前致谢

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-3 model-view-controller rendering


    【解决方案1】:

    我知道你已经接受了这个答案,但我认为你不需要创建自己的模板解析器。

    如果我正确理解了您的问题,那么您正在尝试根据应用当前状态的某些方面来“主题化”您的观点。我以前也用这个花花公子的小控制器方法做过同样的事情:

    prepend_view_path "app/views/#{current_app_code}"
    

    在你的应用控制器的 before_filter 中抛出这个,你的所有控制器都会服从:

    class ApplicationController < ActionController::Base
      before_filter :prepend_view_paths
    
      def prepend_view_paths
        prepend_view_path "app/views/#{current_app_code}"
      end
    
    end
    

    现在,如果“app1”是当前应用程序,则当请求“/users”时,rails 将首先查找“app/views/app1/users/index.html.erb”。

    如果没有找到它,它会回滚到“app/views/users/index.html.erb”的默认位置。

    希望这能给你另一种选择。

    【讨论】:

    • 请注意“current_app_code”是你必须创建的东西。我只是以它为例。
    • 您好,感谢您的建议。我不确定这会起作用,因为默认位置不仅仅是 /views/users 而是 views/shared/users
    • 如果您愿意,也可以添加它。该方法接受一个数组: prepend_view_path(["views/default", "views/custom"])
    • 我仍然无法让它工作。此方法发送当前路径前缀(例如 app1/users/)。使用这种方法,它会查找 /views/shared/app1/users 而不是 /views/shared/users。我必须删除我在解析器中所做的当前前缀“app1”。
    • 原来我不需要在这里编写自己的解析器...谢谢!
    【解决方案2】:

    我相信您必须编写自己的模板解析器。 或许this blog post 可以提供帮助。

    【讨论】:

    • 谢谢!我最初使用链接渲染方法的别名方法,但这似乎资源密集度较低! :)