When rendering a partial (with a layout) in a main layout, the @content_for_layout rendered for the main page content is overwritten with what was rendered for the partial. e.g.
/layouts/application.html.erb
<% render(:layout => "layout_for_partial", :locals => { :name => "Anthony" }) do %>Inside from first block in layout<% end %>
<%= yield %>
<% render(:layout => "layout_for_partial", :locals => { :name => "Ramm" }) do %>Inside from second block in layout<% end %>
/controller/action.html.erb
<%= render(:layout => "layout_for_partial", :partial => "partial_for_use_in_layout", :locals => { :name => "David" }) %>
/controller/_ partial_for_use_in_layout
Inside from partial (<%= name %>)
/controller/_layout_for_partial.html.erb
Before (<%= name %>)
<%= yield %>
After
This should render as
Before (Anthony)
Inside from partial (Anthony)
After
Before (David)
Inside from partial (David)
After
Before (Ramm)
Inside from partial (Ramm)
After
But actually renders as
Before (Anthony)
Inside from partial (Anthony)
After
Inside from partial (Anthony)
Before (Ramm)
Inside from partial (Ramm)
After
This is because the content is rendered before the layout and stored in @content_for_layout, the layout is then rendered and when another
render :layout => 'blahblah', :partial => 'any_other_partial'
is run @content_for_layout is overwritten by the rendered result from this call. So when yield is called from the layout, the contents of this rendered partial are returned again.
This patch adds fixes this problems and adds tests to ensure it works correctly.