Railsy sprawdzają, czy yield: area jest zdefiniowany w content_for

97

Chcę wykonać renderowanie warunkowe na poziomie układu w oparciu o rzeczywisty zdefiniowany szablon content_for(:an__area), masz jakiś pomysł, jak to zrobić?

William Yeung
źródło
Zobacz moją odpowiedź dotyczącą tworzenia metody pomocniczej do hermetyzacji tego zachowania w Rails 3.
tristanm

Odpowiedzi:

217

@content_for_whateverjest przestarzałe. content_for?Zamiast tego użyj w ten sposób:

<% if content_for?(:whatever) %>
  <div><%= yield(:whatever) %></div>
<% end %>
gudleik
źródło
16
Helper content_for?istnieje tylko w Railsach 3. W Railsach 2 można użyć @content_for_...zmiennej instancji.
bynajmniej
10

nie jest konieczne do stworzenia metody pomocniczej:

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

to oczywiście Twoim zdaniem:

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

Używam tego cały czas, aby warunkowo przechodzić między układem jednokolumnowym a dwumolowym

efalcao
źródło
2
<%if content_for?(:content)%>
  <%= yield(:content) %>
<%end%>
gregwinn
źródło
2

Potrafi stworzyć pomocnika:

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

I użyj tego w swoim układzie:

<% if content_defined?(:an__area) %>
  <h1>An area is defined: <%= yield :an__area %></h1>
<% end %>
Nacięcie
źródło
To nie daje odpowiedzi na pytanie. Aby skrytykować lub poprosić autora o wyjaśnienie, zostaw komentarz pod jego postem.
eirikir
Zgadzam się @eirikir, nie jestem pewien, co myślała moja 6-letnia młodsza wersja. Przedłużam i zostawiam odpowiedź dla tych, którzy nadal są na Railsach 2 .. bez zbędnej preambuły;)
Nick
1

Ok, mam zamiar bezwstydnie odpowiedzieć sobie, ponieważ nikt nie odpowiedział, a ja już znalazłem odpowiedź :) Zdefiniuj to jako metodę pomocniczą w application_helper.rb lub w innym miejscu, które uważasz za wygodne.

  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
źródło
No cóż, podoba mi się twoja odpowiedź, ale ... Drobna uwaga, instance_variable_defined?(content_var_name)jest trochę zgrabniejsza niż zamiast sprawdzać, czy jest zerowa. Druga ważna kwestia, zmienna content_for instance jest przestarzała, więc Twoje rozwiązanie nie jest przyszłościowe
Dave Nolan
1

Nie jestem pewien wpływu dwukrotnego wywołania wydajności, ale zrobi to niezależnie od wewnętrznej implementacji zysku (@content_for_xyz jest przestarzałe) i bez dodatkowego kodu lub metod pomocniczych:

<% if yield :sidebar %>
  <div id="sidebar">
    <%= yield :sidebar %>
  </div>
<% end %>
Enrico
źródło