Rails checam se yield: area está definida em content_for

97

Eu quero fazer uma renderização condicional no nível de layout com base no modelo real definido content_for(:an__area), alguma ideia de como fazer isso?

William Yeung
fonte
Veja minha resposta para criar um método auxiliar para encapsular esse comportamento no Rails 3.
tristanm

Respostas:

217

@content_for_whateverestá obsoleto. Use em seu content_for?lugar, assim:

<% if content_for?(:whatever) %>
  <div><%= yield(:whatever) %></div>
<% end %>
Gudleik
fonte
16
Helper content_for?existe apenas no Rails 3. No Rails 2 você pode usar a @content_for_...variável de instância.
para que não seja
10

não é realmente necessário para criar um método auxiliar:

<% if @content_for_sidebar %>
  <div id="sidebar">
    <%= yield :sidebar %>
  </div>
<% end %>

então é claro em sua opinião:

<% content_for :sidebar do %>
  ...
<% end %>

Eu uso isso o tempo todo para ir condicionalmente entre um layout de uma coluna e duas colunas

efalcao
fonte
2
<%if content_for?(:content)%>
  <%= yield(:content) %>
<%end%>
Gregwinn
fonte
2

Pode criar um ajudante:

def content_defined?(var)
  content_var_name="@content_for_#{var}"    
  !instance_variable_get(content_var_name).nil?
end

E use isso em seu layout:

<% if content_defined?(:an__area) %>
  <h1>An area is defined: <%= yield :an__area %></h1>
<% end %>
usuario
fonte
Isso não fornece uma resposta para a pergunta. Para criticar ou solicitar esclarecimentos de um autor, deixe um comentário abaixo de sua postagem.
eirikir
Eu concordo, @eirikir, não tenho certeza do que meu eu de 6 anos mais jovem estava pensando. Estou estendendo e deixando minha resposta para aqueles que ainda estão no Rails 2 .. sem preâmbulos desnecessários;)
Nick,
1

Ok, vou fazer uma auto-resposta descaradamente, pois ninguém respondeu e eu já encontrei a resposta :) Defina isso como um método auxiliar em application_helper.rb ou em qualquer lugar que você achar conveniente.

  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
William Yeung
fonte
Heh bem, eu gosto da sua auto-resposta, mas ... Menor ponto, instance_variable_defined?(content_var_name)é um pouco mais puro do que em vez de testar se é nulo. Segundo ponto importante, a variável de instância content_for está obsoleta, então sua solução não é à prova de futuro
Dave Nolan
1

Não tenho certeza das implicações de desempenho de chamar yield duas vezes, mas isso funcionará independentemente da implementação interna de yield (@content_for_xyz está obsoleto) e sem nenhum código extra ou métodos auxiliares:

<% if yield :sidebar %>
  <div id="sidebar">
    <%= yield :sidebar %>
  </div>
<% end %>
Enrico
fonte