Monday, November 30, 2009

Clearing out content in content_for

In rails, multiple calls to content_for append their body's together and yield the concatenation of all the calls. Conceptually, this looks something like:

<% content_for :title do %>
<% end %>
<% content_for :title do %>
<% end %>

producing "Hello World" when you call
<% yield :title %>

In my current project, I was using redbox to create popup windows (see next post for details). In some cases, I wanted to have multiple popup windows on the same page. However, when I created those popups, each partial had a content_for :title and I was ending up with later popups having titles that contained all the words from previous titles.

After a little digging, I decided I needed a version of content_for that reset the value rather than appending to it. I found some old patches for rails that changed how content_for worked, but I thought it would be cleaner to have a new method that set the content_for variable rather than patching the version in rails.

module ActionView
module Helpers
module CaptureHelper
def set_content_for(name, content = nil, &block)
ivar = "@content_for_#{name}"
instance_variable_set(ivar, nil)
content_for(name, content, &block)

by putting this in /config/initializers it's automatically loaded by rails at startup. You use it just like you'd use content_for
<% set_content_for :title do %>
<end %>

but it clears out the current value of the section before setting it to the content of your new block.


At 9:59 PM , Blogger AmberlyThrower said...

This comment has been removed by a blog administrator.

At 6:14 AM , Blogger Jurriaan said...

This doesn't work anymore
you can use

@view_flow.set :identifier, value

At 7:42 AM , Blogger Michael Mahemoff said...

Actually, I found this works with Rails 3.1:

@view_flow.content_delete :title
content_for :title do
This is the one and only title

At 7:43 AM , Blogger Michael Mahemoff said...

(That last line should be indented of course.)

At 11:41 AM , Anonymous John Naegle said...

That should be @view_flow.content.delete(:title)

At 5:23 PM , Blogger Michael Mahemoff said...

Ah yes, need the . there, so should be:

@view_flow.content.delete :title
content_for :title do

(For reference - always use @view_flow here, it's a hard-coded Rails name, not a variable.)


Post a Comment

Subscribe to Post Comments [Atom]

Links to this post:

Create a Link

<< Home