11

I have multiple partials which may or may not be included in a given layout... and they often have javascript required for just the content of that partial... but I want the javascript loaded in the head.

so I'll generally have something like:

<html>
  <head>
    <title><%= @page_title %></title>
    <%= yield :head %>
  </head>
...etc

and in partial 1:

<% content_for :head do %>
      <%= javascript_tag 'partial_one_js' %>
<% end %>

and in partial 2:

<% content_for :head do %>
      <%= javascript_tag 'partial_two_js' %>
<% end %>

But whichever is defined second blows away the content coming from the first.

There is no way to combine the partials.

I'd like to be able to concatenate them without doing something totally hacky. It also has to work if only one or neither is present.

... and I'd especially rather avoid:

<html>
  <head>
    <title><%= @page_title %></title>
    <%= yield :head_one %>
    <%= yield :head_two %>
  </head>

... ick

So... does anybody have a solution?

Taryn East
  • 27,486
  • 9
  • 86
  • 108
  • [this](http://stackoverflow.com/questions/5631302/multiple-content-for-on-the-same-page) question depicts someone who is having the opposite problem from yourself, i.e. they are looking for a way to prevent `content_for` from appending yield blocks - perhaps it will help, I'd like to know how to do this too – stephenmurdoch Oct 24 '11 at 17:01
  • Thanks - that might be useful to play with. Looking at the apidock info on content_for, it says that content_for concatenates... but that wasn't my experience of it. :( I might test it a bit more thoroughly and see for sure. – Taryn East Oct 24 '11 at 17:08
  • 1
    Actually, after testing it out and reading the docs myself, I can confirm that content_for does indeed concatenate. So something funny is going on with your app. I hate it when that happens – stephenmurdoch Oct 24 '11 at 17:19
  • 2
    In rails4 you can call contents_for with flush as true. Like this: ` <% content_for :body, flush: true do %> ` – Gurpreet Jan 01 '14 at 17:33
  • Ya - probably an old rails-version thing. Thanks. – Taryn East Jan 12 '14 at 00:00

1 Answers1

22

Use content_for to retrieve the stored content rather than yield.

<html>
  <head>
    <title><%= @page_title %></title>
    <%= content_for :head %>
  </head>
...etc

From the source docs:

# Note that content_for concatenates the blocks it is given for a particular
# identifier in order. For example:
#
#   <% content_for :navigation do %>
#     <li><%= link_to 'Home', :action => 'index' %></li>
#   <% end %>
#
#   <%#  Add some other content, or use a different template: %>
#
#   <% content_for :navigation do %>
#     <li><%= link_to 'Login', :action => 'login' %></li>
#   <% end %>
#
# Then, in another template or layout, this code would render both links in order:
#
#   <ul><%= content_for :navigation %></ul>
Douglas F Shearer
  • 25,952
  • 2
  • 48
  • 48