Rails проверяет, определена ли yield: area в content_for

97

Я хочу сделать условный рендеринг на уровне макета на основе фактического определенного шаблона content_for(:an__area), есть идеи, как это сделать?

Уильям Юнг
источник
См. Мой ответ о создании вспомогательного метода для инкапсуляции этого поведения в Rails 3.
tristanm

Ответы:

217

@content_for_whateverустарела. Используйте content_for?вместо этого, например:

<% if content_for?(:whatever) %>
  <div><%= yield(:whatever) %></div>
<% end %>
гудлейк
источник
16
Помощник content_for?существует только в Rails 3. В Rails 2 вы можете использовать @content_for_...переменную экземпляра.
дабы
10

на самом деле не нужно создавать вспомогательный метод:

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

тогда, конечно, на ваш взгляд:

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

Я использую это все время, чтобы условно переходить между макетом в один и два столбца.

Efalcao
источник
2
<%if content_for?(:content)%>
  <%= yield(:content) %>
<%end%>
Gregwinn
источник
2

Может создать помощника:

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

И используйте это в своем макете:

<% if content_defined?(:an__area) %>
  <h1>An area is defined: <%= yield :an__area %></h1>
<% end %>
Ник
источник
Это не дает ответа на вопрос. Чтобы критиковать или запрашивать разъяснения у автора, оставьте комментарий под его сообщением.
eirikir
Я согласен с @eirikir, не знаю, о чем думал я, на 6 лет моложе. Я расширяю и оставляю свой ответ для тех, кто все еще использует Rails 2 ... без ненужной преамбулы;)
Ник,
1

Хорошо, я собираюсь беззастенчиво ответить себе, так как никто не ответил, и я уже нашел ответ :) Определите это как вспомогательный метод либо в application_helper.rb, либо в любом другом месте, которое вы сочтете удобным.

  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
Уильям Юнг
источник
Хех, мне нравится твой самоответчик, но ... Незначительное замечание, instance_variable_defined?(content_var_name)это немного лучше, чем вместо того, чтобы проверять, равен ли он нулю. Второй важный момент: переменная экземпляра content_for устарела, поэтому ваше решение не годится для будущего
Дэйв Нолан,
1

Я не уверен в последствиях для производительности двойного вызова yield, но это будет происходить независимо от внутренней реализации yield (@content_for_xyz устарело) и без какого-либо дополнительного кода или вспомогательных методов:

<% if yield :sidebar %>
  <div id="sidebar">
    <%= yield :sidebar %>
  </div>
<% end %>
Энрико
источник