Rails check if yield :area is defined in content_for

Ruby on-RailsLayoutYield

Ruby on-Rails Problem Overview


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?

Ruby on-Rails Solutions


Solution 1 - Ruby on-Rails

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

<% if content_for?(:whatever) %>
  <div><%= yield(:whatever) %></div>
<% end %>

Solution 2 - Ruby on-Rails

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

Solution 3 - Ruby on-Rails

<%if content_for?(:content)%>
  <%= yield(:content) %>
<%end%>

Solution 4 - Ruby on-Rails

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 %>

Solution 5 - Ruby on-Rails

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

Solution 6 - Ruby on-Rails

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 %>

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionWilliam YeungView Question on Stackoverflow
Solution 1 - Ruby on-RailsgudleikView Answer on Stackoverflow
Solution 2 - Ruby on-RailsefalcaoView Answer on Stackoverflow
Solution 3 - Ruby on-RailsgregwinnView Answer on Stackoverflow
Solution 4 - Ruby on-RailsNick BView Answer on Stackoverflow
Solution 5 - Ruby on-RailsWilliam YeungView Answer on Stackoverflow
Solution 6 - Ruby on-RailsEnricoView Answer on Stackoverflow