Rails检查是否在content_for中定义了yield:area


97

我想根据已定义的实际模板在布局级别进行条件渲染content_for(:an__area),任何想法如何完成?


见我的回答创建一个辅助方法来封装此行为的Rails 3
tristanm

Answers:


217

@content_for_whatever不推荐使用。使用content_for?代替,像这样:

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

16
Helper content_for?仅存在于Rails 3中。在Rails 2中,您可以使用@content_for_...实例变量。
以免2010年

10

创建一个辅助方法并不是必需的:

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

那当然在您看来:

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

我一直都用这个来有条件地在一列和两列之间切换



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 2015年

我同意@eirikir,不确定我6岁以下的年轻人在想什么。对于那些仍在Rails 2 ..上但没有不必要的序言的人,我正在扩展并留我的答案;)
Nick

1

好的,我将无耻地做一个自我答复,因为没有人回答,而且我已经找到答案了。

  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实例变量,因此您的解决方案不再适用于未来
Dave Nolan

1

我不确定两次调用yield的性能含义,但是无论yield的内部实现如何(@content_for_xyz已弃用)且没有任何额外的代码或辅助方法,都可以这样做:

<% if yield :sidebar %>
  <div id="sidebar">
    <%= yield :sidebar %>
  </div>
<% end %>
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.