Beware rendering multiple partials with layouts

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.

Viewing 1 Comment

 
close Reblog this comment
blog comments powered by Disqus