I have a simple yield use case and for some unknown reason the default case is never shown:
In my super_admin layout I have:
<%= yield :body_id || \'s
You can use content_for?(:body_id)
, the code will be like.
<%= content_for?(:body_id) ? yield(:body_id) : 'super_admin_main' %>
I know this is an old question but I have a solution for Rails 2.3.
I've extended shingara's yield_or helper method above so it can now accept a block:
module ApplicationHelper
def yield_or(name, content = nil, &block)
ivar = "@content_for_#{name}"
if instance_variable_defined?(ivar)
content = instance_variable_get(ivar)
else
content = block_given? ? capture(&block) : content
end
block_given? ? concat(content) : content
end
end
and this can be used in your templates:
<% yield_or :something do %>
<p>something else</p>
<% end %>
or
<%= yield_or :something, 'something else' %>
Why no test if there are a content_for or not define in view compilation.
In the content_for code we can see :
def content_for(name, content = nil, &block)
ivar = "@content_for_#{name}"
content = capture(&block) if block_given?
instance_variable_set(ivar, "#{instance_variable_get(ivar)}#{content}".html_safe)
nil
end
So in your case, the @content_for_body_id
is define if a content_for is in your view.
You can made :
<%= instance_variable_defined?('@content_for_body_id') ? yield(:body_id) : 'super_admin_main' %>
If you prefere you can generate an helper after
def yield_or(part, result)
instance_variable_defined?("@content_for_#{part}") ? instance_variable_get("@content_for_#{part}") : result
end
and call it in your view by
<%= yield_or(:body_id, 'super_admin_main') %>
It's works only with Rails 2.3.x
In Rails 3 :
there are this method content_for?
<div class= <%= (yield :content_with_bunners).present? ? yield(:content_with_bunners) : "col-md-10"%>>
In rails 3
raises undefined method `present'
Try <%= yield(:title).presence || 'My Default Title' %>
Object#presence
is equivalent to object.present? ? object : nil
(AS 3 rc docs), and essentially allows the traditional syntax with the titles.