ruby-on-railslayoutnested

Nested Layouts in Rails


I'm having trouble finding a way to do the following:

Let's say in my application.html.erb I have the following

<div id="one" >
  <%= yield %>
</div>

Then I want to have another layout file asdf.html.erb

<div id="two">
  <%= yield %>
</div>

I want the final output to be

<div id="one">
  <div id="two">
     <%= yield %>
  </div>
</div>

Is it possible? Thanks.


Solution

  • By default, application.html.erb is your layout. You can render a default sub-layout by calling it as a partial from your application layout:

    # app/views/layouts/application.html.erb
    <div id="one" >
        <%= render "layouts/asdf" %>
    </div>
    
    # app/views/layouts/_asdf.html.erb
    <div id="two">
        <%= yield %>
    </div>
    

    This will output the following:

    <div id="one">
       <div id="two">
          <%= yield %>
       </div>
    </div>
    

    Alternatively, if you're looking to conditionally render layouts on a controller-by-controller basis, you should consider using nested layouts. From the documentation:

    On pages generated by NewsController, you want to hide the top menu and add a right menu:

    # app/views/layouts/news.html.erb
    <% content_for :stylesheets do %>
      #top_menu {display: none}
      #right_menu {float: right; background-color: yellow; color: black}
    <% end %>
    <% content_for :content do %>
      <div id="right_menu">Right menu items here</div>
      <%= content_for?(:news_content) ? yield(:news_content) : yield %>
    <% end %>
    <%= render template: "layouts/application" %>
    

    The News views will use the new layout, hiding the top menu and adding a new right menu inside the "content" div.