Nested Layouts 7

Posted by pratik
on Tuesday, July 07

Don’t think the nested layouts get any simpler in Rails.

1
2
3
4
5
6
module ApplicationHelper
  def parent_layout(layout)
    @content_for_layout = self.output_buffer
    self.output_buffer = render(:file => "layouts/#{layout}")
  end
end

Now using the parent_layout helper method inside your layouts for nesting :

1
2
3
4
5
# items.html.erb
<h1>Just my items</h1>
<%= yield %>

<% parent_layout 'master' %>

and the parent layout of items – the master layout :

1
2
3
4
5
6
7
# master.html.erb
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
  <head><title>Hello World</title></head>
  <body>
    <%= yield %>
  </body>
</html>

Now, the items layout will always be wrapped under the master layout. Just make sure that the parent_layout call is always on the last line using <%. This technique also works for nesting deeper than a single level.

Comments

Leave a response

  1. Ben JohnsonJuly 07, 2009 @ 11:43 PM

    Nice post, not sure if you’ve seen this or not.

    http://pastie.org/537822

    But I’ve been using this for years and its worked out great. The syntax is a little different though:

    <% inside_layout 'base' do %>
    my content
    <%= yield %>
    <% end %>
    
  2. Steven BristolJuly 08, 2009 @ 12:04 AM

    Nice, but I think in general, if you need to do this, you’ve already made a mistake higher up in the stack. (Doesn’t mean I don’t love you.)

  3. Jon SidnellJuly 08, 2009 @ 01:06 AM

    Thank you! I’ve been looking for a technique like this for some time now :)

    I’ll give it a try next time I’m building something in Rails!

  4. Kyle CrumJuly 08, 2009 @ 07:39 AM

    I don’t understand why this would ever be needed, especially when there is a layout parameter to the render method. Any template that you render, whether it’s a partial or not, can be wrapped in a layout, which means you can have as many layouts within a page as you want.

  5. PratikJuly 08, 2009 @ 09:23 AM

    @Steve lol! My main use case is for admin layouts, where I have to add some menu on the top/bottom to the regular application layout.

    @Kyle Partial layouts are slightly different.

    @Ben Yeah I had seen that again. Still find my solution more elegant :P Yours is more flexible though.

  6. BotanicusJuly 08, 2009 @ 12:59 PM

    Nice, but I personaly prefer template inheritance (I hope this is basically what is your post about) (great description at Django docs: http://docs.djangoproject.com/en/dev/topics/templates/#template-inheritance). I implement it in my tiny rack-based framework called Rango: http://github.com/botanicus/rango … and here is showcase: http://gist.github.com/88171 ATM no more docs, it’s in quite early stage of development (but already works nice and fast).

  7. Insane DreamerDecember 01, 2009 @ 03:40 AM

    How is this better than just putting <% render :file => ‘layouts/master’ %> in the “inner” layout, and eliminate the need for one more helper?

Comment