Rails Rails nested layout

kikyous · 2016年04月12日 · 最后由 kikyous 回复于 2016年04月13日 · 2282 次阅读

http://kikyo.us/2016/04/12/rails-nested-layout.html

问题

  • 某 rails 项目 layouts/application.html.erb
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title><%= @title  %></title>
    <meta name="keywords" content="<%= @keywords %>" />
    <meta name="description" content="<%= @description %>" />
    <%= csrf_meta_tags %>
    <%= action_cable_meta_tag %>

    <%= stylesheet_link_tag    'application', media: 'all', 'data-turbolinks-track' => true %>
    <%= javascript_include_tag 'application', 'data-turbolinks-track' => true %>
  </head>
  <body>
    <%= yield %>
    <footer>
      ...
    </footer>
  </body>
</html>

现在需要另一个子 layout,他继承自 layouts/application.html.erb,又有自己的内容,该怎么办呢?尽量把公共的部分抽出来,然后在不同的 layout 之间共享吗?

  • layouts/main.html.erb
<!DOCTYPE html>
<html>
  <%= render 'head' %>
  <body>
    <div class="container">
      <%= yield %>
      <div class="sidebar">
        ...
      </div>
    </div>
    <%= render 'footer' %>
  </body>
</html>

这样可以解决问题但不完美,没有体现出继承关系来,如果 layout 复杂,可能需要抽出很多的共享部分出来,而且子模板还是有很多重复的代码。

嵌套模板

application_helper.rb中加入下面的方法:

def parent_layout(layout)
  @view_flow.set(:layout, output_buffer)
  output = render(:file => "layouts/#{layout}")
  self.output_buffer = ActionView::OutputBuffer.new(output)
end

然后layouts/main.html.erb就可以变成这样的了

<div class="container">
  <%= yield %>
  <div class="sidebar">
    ...
  </div>
</div>

<% parent_layout "application" %>

直接在子模板中指定父模板,完美的继承关系,而且可以进行多次,比如

  • layouts/profile.html.erb
<div class="profile">
  <%= render 'profile_nav' %>
  <%= yield %>
</div>

<% parent_layout "main" %>

最后这 3 个 layout 的关系如下:

application < main < profile

Reference

http://m.onkey.org/nested-layouts

1 楼 已删除

layouts/profile.html.erb 中可以直接引用 application 的:

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

See Using Nested Layouts

#3 楼 @ashchan 嗯,但是我觉得 rails guide 里面说的 Using Nested Layouts 没有 parent_layout 好

需要 登录 后方可回复, 如果你还没有账号请 注册新账号