Lighthouse has a new layout. Prefer the old one? Return to the old layout, and switch back any time from the link at the top of each page.

This project is archived and is in readonly mode.

Rails 3.0 yield :name doesn't show content_for :name

#5708

With Rails 3.0 yield(:name) doesn't yield the content defined in content_for(:name) when yield(:name) and content_for(:name) are called from different partials, both partials rendered from the same layout.

FAILING EXAMPLE (no content renders in the script tag)

<!-- app/views/layouts/application.html.erb -->
<html>
  <%= render "shared/head" %>
  <body>
    <%= render "shared/messages" %>
    <%= yield %>
  </body>
</html>
<!-- app/views/shared/_head.html.erb -->
<head>
  <script type="text/javascript">
    <%= yield :script %>
  </script>
</head>
<!-- app/views/shared/_messages.html.erb -->
<% if notice %>
  <div id="notice_indicator"></div>
  <% content_for :script do %>
    alert("<%= escape_javascript(notice) %>");
  <% end %>
<% end %>

PASSING EXAMPLE (content renders in script tag)

<!-- app/views/layouts/application.html.erb -->
<html>
  <head>
    <script type="text/javascript">
      <%= yield :script %>
    </script>
  </head>
  <body>
    <%= render "shared/messages" %>
    <%= yield %>
  </body>
</html>
<!-- app/views/shared/_messages.html.erb -->
<% if notice %>
  <div id="notice_indicator"></div>
  <% content_for :script do %>
    alert("<%= escape_javascript(notice) %>");
  <% end %>
<% end %>

Reported by Matthew Daubert · September 26th, 2010 @ 03:00 PM

State: wontfix
Milestone: none
Assigned to: nobody
Importance: Low

Activity

  1. Jeff Kreeftmeijer
    Jeff Kreeftmeijer

    I was unable to reproduce it on master with this setup:

    application.html.erb:

    <%= render('some_partial') %>
    

    users/_some_partial.html.erb:

    <%= yield(:script) %>
    

    users/index.html.erb:

    <% content_for(:script) { 'works!' } %>
    

    Can anyone else? I'll try to reproduce your exact example later, but I don't think it will make a difference. :)

    September 27th, 2010 @ 07:03 AM

  2. Matthew Daubert
    Matthew Daubert

    Thank you Jeff - Your example works for me, too. I think the problem may be specifically with calling content_for from within a partial and yielding in a different partial. I couldn't find anything in RDoc => CaptureHelper that would indicate that this shouldn't work and I thought it was working in 2.3.9. I'll upload a failing app as soon as I get a few minutes. :)

    September 27th, 2010 @ 12:47 PM

  3. Matthew Daubert
    Matthew Daubert

    Attached is a barebones app that fails for me (Rails 3.0.0, Ruby 1.9.2p0 x86_64-darwin10.4.0, OSX 10.6.4). The partial shared/messages has content_for(:script) but no content is rendered from the layout's yield(:script) statement.

    September 27th, 2010 @ 01:58 PM

  4. Luca Guidi
    Luca Guidi

    IMO this isn't a bug, because AV renders the template first then the layout.

    In your example:
    1. The template is being rendered (main yield)
    2. AV starts with the layout
    2a. It renders shared/head, at this time content_for(:script) wasn't triggered yet, that's because yield doesn't print anything
    2b. It renders shared/messages, now the content are initialized but the above partial was already rendered.

    September 27th, 2010 @ 08:43 PM

  5. Ryan Bigg
    Ryan Bigg
    • State changed from new to wontfix
    • Importance changed from to Low

    Luca is correct.

    If the yield :blah is processed before the content_for :blah then the yield will output nothing.

    September 27th, 2010 @ 11:15 PM

  6. Ryan Bigg
    Ryan Bigg
    • Tag changed from rails3.0.0 to 3.0.0

    September 27th, 2010 @ 11:15 PM