Nested layouts in rails are pretty neato. You can get a lot of styles and consistency across your site without writing a whole lot of code. I wanted to take advantage of all of the styles I have in place in my app/views/layouts/application.html.erb file, but also wanted to render another custom layout with a sidebar and content area inside the application layout for the static pages on my site. nested layouts

My static pages are all rendered by the PagesController, so I created a file called app/views/layouts/pages.html.erb to hold the HTML for the sidebar and main content of those pages.

To nest the pages layout HTML inside the application layout HTML, I used a content_for tag. In the app/views/layouts/application.html.erb I accounted for yielding a block named :pages_layout. Now, when rendering a page, if a block called content_for :pages_layout appears in the HTML, we’ll use the special pages layout.

<!-- app/views/layouts/application.html.erb -->
<!DOCTYPE html>
<html>
  <head>...</head>
  <body>
    <%= render 'shared/navbar' %>

    <%= content_for?(:pages_layout) ? yield(:pages_layout) : yield %>

    <%= render 'shared/footer' %>
  </body>
</html>

Then in app/views/layouts/pages.html.erb, I wrapped the HTML in a content_for? block and provided a yield for the HTML that comes from the static pages themselves (ex: app/views/pages/about.html.erb). By the way, there is no Rails MagicTM in the naming of :pages_layout. You can call it whatever you want as long as you call it the same thing in both places.

<!-- app/views/layouts/pages.html.erb -->

<% content_for :pages_layout do %>
  <div class="sidebar">
    <h3>This is my sidebar</h3>
    <p>Yay sidebar stuff.</p>
  </div>

  <div class="main-content">
    <!-- Content from the static pages, ex: app/views/pages/about.html.erb
         will be rendered by this yield. -->
    <%= yield %>
  </div>
<% end %>

<!-- be sure to include this render tag for the application layout -->
<%= render template: 'layouts/application' %>

So the app knows to use this pages layout for all of the static pages, I set the default layout in the PagesController:

# app/controllers/pages_controller.rb

class PagesController < ApplicationController
  layout 'pages'

  def about; end
  def contact; end
  def store; end
end

Now whatever I put in the app/views/pages/about.html.erb (as well as Contact and Store pages) will appear with a navbar, background image, sidebar, main content, and footer. And all I have to include in that file is the HTML for the main content area:

</h1>About</h1>
<p>Hello, my name is Anne. Sometimes I write code.</p>

This is so much less code and much easier to maintain than building out a sidebar and main content area for each of these static pages. #winning

If you want to, you can nest endlessly by following that same pattern. See the Rails Docs for more help.