Render engine within application layout

后端 未结 3 523
清歌不尽
清歌不尽 2021-01-31 16:47

Background

I am creating a application that is made up of a core and several modules. The modules are rails engines, and provide the actual functionality as the core i

相关标签:
3条回答
  • 2021-01-31 17:13

    I have successfully used layouts of my parent application in my engines. Firstly, based on Section 4.3.2 of the Rails Guides (Engines), in order to access the parent applications ApplicationController's variables (like session, as you're using above), you need to replace the engine's application_controller.rb from this that you currently have:

    module Module1
      class ApplicationController < ActionController::Base
        layout "core"
      end
    end
    

    to this:

    class Module1::ApplicationController < ::ApplicationController
    end
    

    This will inherit the parent application's ApplicationController, along with all it's variables.

    Secondly, you'll need to delete the file app/views/layouts/application.html.erb from your engine views, as it will not be needed since you're using the parent application's one.

    Now when you render a view of Module1 from the parent application, the layout of the parent application will be used, and all the session[] variables will be evaluated correctly.

    Do not forget to add the words "main_app." before each link in your layouts, otherwise it will try and look for the paths in the engine instead of the parent application. For example, if the layout in the parent application includes a link to some_path (that is a view in the parent application), when showing a view in the engine that uses this layout will try and look for some_path in the Engine instead of the parent application. You will need to change the link to main_app.some_path for it to work.

    Hope this helps.

    0 讨论(0)
  • 2021-01-31 17:30

    I also did the same thing in my application. All I did was:

    1. Delete the engine layout in /app/view/layouts/
    2. Change your application_controller to

      module EngineModule
        class ApplicationController < ::ApplicationController
          layout 'layouts/application' 
        end
      end
      
    3. In your views, if you want to refer to any path such as login_path, it can be referred via main_app.login_path

    0 讨论(0)
  • 2021-01-31 17:36

    Use layout 'layouts/application'

    And if you don't want to use main_app.your_path you can also add:

    module YourEngine
      module ApplicationHelper
        def method_missing(method, *args, &block)
          if (method.to_s.end_with?('_path') || method.to_s.end_with?('_url')) && main_app.respond_to?(method)
            main_app.send(method, *args)
          else
            super
          end
        end
      end
    end
    
    0 讨论(0)
提交回复
热议问题