I want to do a conditional rendering at the layout level based on the actual template has defined content_for(:an__area)
, any idea how to get this done?

- 8,178
- 8
- 39
- 85

- 10,368
- 9
- 36
- 42
-
See my [answer](http://stackoverflow.com/questions/3347322/yield-if-content-render-something-otherwise-rails-3/7409626#7409626) for creating a helper method to encapsulate this behaviour in Rails 3. – tristanm Sep 13 '11 at 23:19
7 Answers
@content_for_whatever
is deprecated.
Use content_for?
instead, like this:
<% if content_for?(:whatever) %>
<div><%= yield(:whatever) %></div>
<% end %>

- 8,178
- 8
- 39
- 85

- 3,011
- 1
- 18
- 4
-
16Helper `content_for?` exists only in Rails 3. In Rails 2 you could use `@content_for_...` instance variable. – lest Oct 08 '10 at 14:57
not really necessary to create a helper method:
<% if @content_for_sidebar %>
<div id="sidebar">
<%= yield :sidebar %>
</div>
<% end %>
then of course in your view:
<% content_for :sidebar do %>
...
<% end %>
I use this all the time to conditionally go between a one column and two column layout

- 5,106
- 1
- 24
- 19
Can create a helper:
def content_defined?(var)
content_var_name="@content_for_#{var}"
!instance_variable_get(content_var_name).nil?
end
And use this in your layout:
<% if content_defined?(:an__area) %>
<h1>An area is defined: <%= yield :an__area %></h1>
<% end %>

- 7,639
- 2
- 32
- 28
-
This does not provide an answer to the question. To critique or request clarification from an author, leave a comment below their post. – eirikir Oct 06 '15 at 22:19
-
I agree @eirikir, not sure what my 6 year younger self was thinking. I'm extending & leaving my answer in for those still on Rails 2.. without the unnecessary preamble ;) – Nick B Oct 07 '15 at 00:52
I'm not sure of the performance implications of calling yield twice, but this will do regardless of the internal implementation of yield (@content_for_xyz is deprecated) and without any extra code or helper methods:
<% if yield :sidebar %>
<div id="sidebar">
<%= yield :sidebar %>
</div>
<% end %>

- 19
- 1
Ok I am going to shamelessly do a self reply as no one has answered and I have already found the answer :) Define this as a helper method either in application_helper.rb or anywhere you found convenient.
def content_defined?(symbol)
content_var_name="@content_for_" +
if symbol.kind_of? Symbol
symbol.to_s
elsif symbol.kind_of? String
symbol
else
raise "Parameter symbol must be string or symbol"
end
!instance_variable_get(content_var_name).nil?
end

- 10,368
- 9
- 36
- 42
-
Heh well I like your self-reply but... Minor point, `instance_variable_defined?(content_var_name)` is a bit neater than instead of testing whether it is nil. Second bigger point, the content_for instance variable is deprecated so your solution is not future proof – Dave Nolan Jan 23 '09 at 22:51
I use @view_flow and value of the content method before checking if the content is present in the view like this:
@view_flow.content[:header_left_or_whatever_the_name_of_your_block_is].present?
Recently stumbled upon it when showing all local, global and instance variables of self in the console with byebug. I’m a fan using this because it’s straight from Rails, won’t throw an error, won’t hide anything w “Rails magic”, returns a definite true or false, + only checks the content in the current context of the view being rendered.
@view_flow is an instance attribute of ActionView::Context and because Action View contexts are supplied to Action Controller to render a template it will be available to any view that has been rendered by Rails. Although it checks for content, the content_for block will not be yielded if it isn’t there. So it’s been my perfect solution in similar situations.

- 26
- 2