应用程序布局中的渲染引擎 [英] Render engine within application layout

查看:42
本文介绍了应用程序布局中的渲染引擎的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在创建一个由一个核心和几个模块组成的应用程序.这些模块是 rails 引擎,并提供实际功能,因为核心本身仅充当主机.引擎从 /lib 托管并安装在各自的路径上.

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 itself only acts as a host. The engines are hosted from /lib and mounted at their respective paths.

coreApp
└──lib
   ├── module1
   ├── module2
   └── etc

然后像这样安装模块

mount Module1::Engine => "/module1", :as => "module1"
mount Module2::Engine => "/module2", :as => "module2"

核心还负责处理会话,尽管登录本身是由模块完成的.

The core is also responsible for handeling the session, although the login itself is done by a module.

我还没有找到一种与引擎共享核心应用程序布局的好方法.到目前为止,这就是我为引擎提供布局的方式:

I have yet to find a great way of sharing the core application layout with the engines. As of now, this is how I make the layout available to the engines:

coreApp
└── app
    └── views
        └── layouts
            ├── application.html.erb
            └── core.html.erb

文件core.html.erb只包含

<%= render :template => 'layouts/application' %>

然后像这样包含在每个模块中

Is is then included in each module like this

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

虽然它不是特别优雅,但它工作正常,并且模块的内容呈现在应用程序布局中的 yield 语句处.

Although it isn't particularly elegant, it works fine, and the content of the module is rendered where the yield statement in the application layout.

问题如下:

我需要一种方法来包含活动模块的样式表.

I need a way to include the stylesheets of the active module.

标题包含有关登录用户的信息,例如

The header contains information about the logged in user, like

Logged in as <%= @user[:realname] %>

这来自内核home_controller

def index
  @user = User.find_by_id(session[:user])
end

但是当我尝试访问模块时,出现以下错误

But when I try to access the module, I get the following error

NoMethodError in Module1/home#index

You have a nil object when you didn't expect it!
You might have expected an instance of Array.
The error occurred while evaluating nil.[]

显然是指@user.

如何在不对引擎方面进行过多篡改的情况下尽可能优雅和干燥地解决这个问题?

How can this be solved in as elegantly and DRY as possible without too much tampering on the engine side?

我在谷歌上搜索了很多,但我真的不知道如何解决它.可能完全缺乏对 rails 工作原理的了解,因此这个问题很可能对于熟悉 rails 的人来说毫无意义.

I have Googled this a lot but can't really get my head around how to solve it. It might be total lack of insight in how rails works, so there is a good chance this question doesn't even make sense for someone that knows rails well.

如果有任何不清楚或模棱两可的地方,请发表评论,我会尽量详细说明.

Please comment if anything is unclear or ambiguous, and I'll try to elaborate.

推荐答案

我已经成功地在我的引擎中使用了父应用​​程序的布局.首先,基于 Rails 指南(引擎)的第 4.3.2 节,为了访问父应用程序ApplicationController的变量(如session,正如你在上面使用的),你需要从这个替换引擎的application_controller.rb您目前拥有的:

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

到此:

class Module1::ApplicationController < ::ApplicationController
end

这将继承父应用程序的 ApplicationController 及其所有变量.

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

其次,您需要从引擎视图中删除文件 app/views/layouts/application.html.erb,因为您使用的是父应用程序的一个.

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.

现在,当您从父应用程序渲染 Module1 的视图时,将使用父应用程序的布局,并且所有 session[] 变量都将被正确评估.

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.

不要忘记添加main_app"字样.在布局中的每个链接之前,否则它将尝试在引擎而不是父应用程序中查找路径.例如,如果父应用程序中的布局包含指向 some_path(即父应用程序中的视图)的链接,则在使用此布局的引擎中显示视图时将尝试查找 some_path 在引擎而不是父应用程序中.您需要将链接更改为 main_app.some_path 才能使其工作.

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.

希望这会有所帮助.

这篇关于应用程序布局中的渲染引擎的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆