Rails yield and content_for wieird behaviour, `yield :filter` only work if placed after default yield

320 Views Asked by At

Lets say i have this partial i am trying to render

#layouts/_subheader.html.erb
<div class="subheader">
   <%= yield %>
   <%= yield :filters %>
</div>

when i use this partial in a view like this

<%= render 'layouts/sub_header' do %>
   <h2> Content For Yield </h2>
   <% content_for :filters do %>
      <h2> Content for Filters </h2>
   <%  end %>
<% end %>

i am getting the HTML output as

<div class="subheader">
   <h2> Content For Yield </h2>
   <h2> Content for Filters </h2>
</div>

this works as expected, but the problem arises when i change the order of the yield tags in the partial

instead of the above, if i rewrite the partial as

#layouts/_subheader.html.erb
<div class="subheader">
   <%= yield :filters %>
   <%= yield %>
</div>

i am getting output as

<div class="subheader">
   <h2> Content For Yield </h2>
</div>

the content_for :filters is not being rendered.

what an i doing wrong here ? is this the correct behavior or am i doing something wrong ?

what should i do if i have to make the content of the yield :filters appear before the plain yield

EDIT:-

I have tried

#layouts/_subheader.html.erb
<div class="subheader">
   <%= content_for :filters %>
   <%= yield %>
</div>

but it seems to be not working as well.

1

There are 1 best solutions below

0
On BEST ANSWER

Thanks everyone on reddit and @Ezhil i found a solution, this is what i did

what i did is i placed the content_for capture group before the render like this

#index.html.erb
<% content_for :filters do %>      
  <h2> Content for Filters </h2> 
<% end %> 

<%= render 'layouts/sub_header' do %>   
  <h2> Content For Yield </h2> 
<% end %>

and in my partial

#layouts/_subheader.html.erb 
<div class="subheader">     
   <%= content_for :filters %>     
   <%= yield %>
</div>

It's because the block isn't executed until the first yield, so there's no content captured until that runs.