Nested layouts in Rails
I’m working on a new pet project, and I want to keep my layouts nice and DRY. That means I need to nest my layouts. Unfortunately, googling around for how folks were implementing nested layouts put me on the right path, but nothing felt generic enough. I did get put on the right path, though. This post describes my current solution.
The problem scenario is two-fold:
First, we assume that we’re trying to insert a controller-specific layout layer between the most generic layout and the content from the current action’s template.
Generic Header
– Controller-specific header
—- Action-specific content
– Controller-specific footer
Generic footer
Second, the controller may have some inheritance hierarchy that’s more complicated that just inhering from ApplicationController, and I want to render the most specific layout available. For example, my hierarchy might look like this:
- UsersController (defaults for all user-accessible controllers)
- AccountController
- PuppiesController
- AdminController (defaults for all admin-accessible controllers
- SomeAdminThingController
If I’m rendering an action in PuppiesController, I want to first try to render layouts/_puppies.rhtml. If that’s not available, then I’ll try layouts/_users.rhtml. And if there’s no middle-layer layout available, I just want to render the content.
Here’s the solution:
First, set your default layout in application_controller.rb:
layout 'default'
Ensure you’ve got a matching default.rhtml in app/views/layouts/.
Then, you would place the following method in helpers/application_helper.rb:
module ApplicationHelper
def render_best_inner_layout
layouts = []
c = controller.class
while c != ApplicationController do
layouts << c.controller_name
c = c.superclass
end
while (_layout = layouts.shift)
begin
return render :partial => "/layouts/#{_layout}"
rescue ActionView::MissingTemplate
end
end
return false
end
end
Finally, in your default layout, you call that method where you want to render the nested layout. Notice how if false is returned by the helper method, meaning no mid-tier layout was found, we simply yield.
<%= render_best_inner_layout || yield %>
The limitation is that this doesn’t nest infinitely. E.g., if you have a layout nested layout for ‘users’ and‘puppies’, only puppies will be used, rather than chaining users followed by puppies. This suits my current needs, so I’ll let others improve on it as needed.

You might wanna checkout my take as well : http://m.onkey.org/2009/7/7/nested-layouts