rails prepend_view_path可安装引擎

时间:2012-03-19 11:28:31

标签: ruby-on-rails layout partial-views rails-engines prepend

一方面,我有一个可安装的引擎让我们说Front 前面包含我的资产和几页 它与MainApp隔离。我不希望它触及主应用程序。

另一方面,我希望我的MainApp使用布局和部分Front。 所以我以这种方式设置布局:

class ApplicationController < ActionController::Base
    layout 'front/application'
end

但是前端/应用程序直接引用引擎部分,因为隔离,就像这个

render 'header' # front/ prefix is not required

因此,MainApp视图尝试加载app / views / application / header而不是app / views / front / application / header

为了解决这个问题,我将prepend_view_path设置为:

class ApplicationController < ActionController::Base
    layout 'front/application'
    before_filter :prepend_front
protected
    def prepend_front
       prepend_view_path "app/views/front"
    end
end

但这不起作用,因为引擎路径指向供应商。 引擎将它自己添加到前置路径列表中:〜/ main_app / vendor / private_gems / front-0.0.2 / app / views 我的preprend_front方法创建了这个:〜/ main_app / app / views / front

我试图强制前置正确的路径(但看起来很脏):

prepend_view_path "#{Rails.root}/vendor/private_gems/front-0.0.2/app/views/front"

我不工作,只是让应用程序崩溃......

我被困在这里。也许我的设计错了?

3 个答案:

答案 0 :(得分:2)

杰克的答案是完美的,除非您想在Rails引擎中执行此操作(例如,如果您的引擎本身具有需要不同加载路径的主题&#39;)。在这种情况下,prepend_path和append_path不合适,因为您希望在引擎默认加载路径之前插入新的加载路径,但是在应用程序加载路径之后。

对此的解决方案(仅在Rails 3.2中测试)是将以下内容添加到引擎/lib/my_engine.rb文件中:

config.after_initialize do
  my_engine_root = MyEngine::Engine.root.to_s
  paths = ActionController::Base.view_paths.collect{|p| p.to_s}
  paths = paths.insert(paths.index(my_engine_root + '/app/views'), my_engine_root + '/app/views/themes/my_theme')
  ActionController::Base.view_paths = paths
end

新的加载路径my_engine_root + '/app/views/themes/my_theme'现在就在您的引擎标准加载路径my_engine_root + '/app/views'

之前

答案 1 :(得分:1)

默认情况下,Rails查看视图/文件,但是当它找不到时,它会查看引擎的views /。这意味着您必须附加视图路径,以便Rails将查看主应用程序的视图/然后查看引擎中已修改的路径,最后查看引擎的视图/。这将是堆栈:

  • 主要应用观点/
  • 引擎修改路径(视图/前端/内部引擎)
  • 引擎视图/

要执行此操作,请转到application_controller.rb

class ApplicationController < ActionController::Base

    before_filter :set_views_path

    def set_views_path
        append_view_path FnetIdentityRailsEngine::Engine.root.join('app', 'views', 'front')
    end
end

如果您在引擎中使用修改后的路径添加了视图路径,则无法在主应用程序中覆盖引擎视图。这就是你想要追加的原因。

答案 2 :(得分:0)

最后我删除了isolate属性。 我将视图移动了一个文件夹,因此不在engine_app文件夹中。

唯一的最终结果是将EngineApp :: Engine.url_helper包含在MainApp应用程序控制器中。

前置堆栈如下所示:

  • 主要应用程序前置路径
  • 主要应用视图
  • 引擎视图

所以它基于引擎,然后在顶部添加主应用程序。