Reputation: 6793
I am trying to reduce the repetitive code with the following pattern in an ERB template:
<% if content_for(some_key) %>
<%= yield(some_key) %>
<% else %>
Some default values here
<% end %>
I've tried defining the following method in ApplicationHelper
but understandably it's not working as expected;
def content_for_with_default(key, &block)
if content_for?(key)
yield(key)
else
block.call
end
end
Here's how I'm trying to use it:
<%= content_for_with_default(some_key) do %>
Some default values here
<% end %>
How can I write the content_for_with_default
helper so that it has the intended effect?
Upvotes: 0
Views: 134
Reputation: 5294
Your helper should be like this:
def content_for_with_default(key, &block)
if content_for?(key)
content_for(key)
else
capture(&block)
end
end
EDIT: difference between capture(&block)
and block.call
After the erb file is compiled, the block will be some ruby code like this:
');@output_buffer.append= content_for_with_default('some_key') do @output_buffer.safe_concat('
');
@output_buffer.safe_concat(' Some default values here
'); end
You see, the strings within the block are concatenated to the output_buffer and safe_concate
returns the whole output_buffer.
As a result, block.call
also returns the whole output_buffer. However, capture(&block)
creates a new buffer before calling the block and only returns the content of the block.
Upvotes: 1