Beware rendering multiple partials with layouts

Posted on April 27, 2008
Filed Under Rails |

Want to render more than one partial with the same layout in your page? Beware:

<%= render :partial => ‘p1′, :layout => ‘layouts/p_layout’ %>
<%= render :partial => ‘p2′, :layout => ‘layouts/p_layout’ %>

layouts/p_layout.html.erb

<%= yield :top %>
<%= yield %>
<%= yield :bottom %>
<hr/>

_p1.html.erb

<% content_for :top, 'HeaderFor1' %>
<% content_for :bottom, 'FooterFor1' %>
Content!

_p2.html.erb

<% content_for :top, 'HeaderFor2' %>
<% content_for :bottom, 'FooterFor2' %>
Content!

Did you expect this?

HeaderFor1 Content! FooterFor1


HeaderFor2 Content! FooterFor2


Nope. You get this:

HeaderFor1 Content! FooterFor1


HeaderFor1HeaderFor2 Content! FooterFor1FooterFor2


The instance variables in the layout object retain their values, even between invocations of render. My workaround (since I’m not sure if some would call this a “feature”)…clear the instance variables at the end of your layout.

<%= yield :top %>
<%= yield %>
<%= yield :bottom %>
<hr/>
<% @content_for_top, @content_for_bottom = nil %>

Now it works as I expected.

Comments

Leave a Reply