views:

3907

answers:

6

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?

+1  A: 

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
goodwill
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
+1  A: 

Thanks for the answer. However, is there any benefit to raising when the parameter is not a symbol or string? Seems like unnecessary protection. This method can simplify to:

def content_defined?(var)
  content_var_name="@content_for_#{var}"    
  !instance_variable_get(content_var_name).nil?
end
Nick
+3  A: 

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

efalcao
A: 

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 %>
Enrico
+4  A: 

@content_for_whatever is deprecated. Use content_for? instead, like this:

<% if content_for?(:whatever) %>
  <div><%= yield(:whatever) %></div>
<% end %>
gudleik
Helper `content_for?` exists only in Rails 3. In Rails 2 you could use `@content_for_...` instance variable.
lest
A: 

It's worth noting that the accepted answer is not valid for Rails 2.x. The content_for? method is in the source tree but not yet in a released version in the 2.x branch.

douglasr