Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails: using "content_for" after the corresponding "yield" inside layout

I think this has been asked before but even though I searched Google I haven't come up with a solution.

So this is what I'm trying to do in Rails 2.3.5:

layouts/application.html.erb:
<html>
  <head>
    ... some other stuff
    <%= yield :head %>
  </head>
  <body>
    <% content_for :head, "something that belongs in the head" %>
  </body>
</html>

Notice the yield before the content_for.

I know that Rails - by default - doesn't allow the content of :head to be defined after yield has been used - makes sense.

I even tried hooking into the template render process but no success so far.

So my goal is to be able to define content_for inside partials/templates and have the "yield" somehow delayed and executed just before the response is send to the browser.

Has somebody come up with a solution?

Greetings and thanks, Frank

Update I'll go with weppos's idea and try myself on rack middleware. thanks

like image 521
thenoseman Avatar asked Jan 08 '10 09:01

thenoseman


2 Answers

The rendering process first loads and executes the action template, then decorates the template with the selected layout. The layout is rendered from top to botton, thus you can't add more content to :head after :head is already rendered.

You need to change your strategy. Either place the fragment in a partial and attach it to your action views or use a post-processing strategy such as a Rack module/after_filter to alter the html code directly.

I probably would try to find a better solution based on what I actually need. If you are encountering this issue, chances are the error is somewhere else, perhaps in the app architecture.

like image 158
Simone Carletti Avatar answered Oct 04 '22 07:10

Simone Carletti


There shouldn't be an equals sign in your content_for statement. It should be:

<% content_for :head, "Something that belongs in the head" %>

If you define the content within your templates and partials then it should work. This technique was covered in Railscast episode 8.

like image 23
John Topley Avatar answered Oct 04 '22 07:10

John Topley