如果内容产生,则以其他方式呈现(Rails 3)

时间:2010-07-27 19:44:26

标签: ruby-on-rails views rendering

我已经离开Rails一段时间了,所以也许我错过了一些简单的事情。

你怎么能做到这一点:

<%= yield_or :sidebar do %>
  some default content
<% end %>

甚至:

<%= yield_or_render :sidebar, 'path/to/default/sidebar' %>

在第一种情况下,我正在尝试:

def yield_or(content, &block)
  content_for?(content) ? yield(content) : yield
end

但是这会引发'禁止阻止'错误。

在第二种情况下:

def yield_or_render(content, template)
  content_for?(content) ? yield(content) : render(template)
end

当没有定义内容时,这会有效,但只要我使用content_for覆盖默认内容,它就会抛出同样的错误。

我使用this作为起点,但似乎只有在视图中直接使用时才有效。

谢谢!

3 个答案:

答案 0 :(得分:14)

这样的事情怎么样?

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

Inspiration from this SO question

答案 1 :(得分:5)

试试这个:

# app/helpers/application_helper.rb
def yield_or(name, content = nil, &block)
  if content_for?(name)
    content_for(name)
  else
    block_given? ? capture(&block) : content
   end
end

所以你可以做到

<%= yield_or :something, 'default content' %>

<%= yield_or :something do %>
    block of default content
<% end %>

可以使用

覆盖默认值
<%= content_for :something do %>
    overriding content
<% end %>

答案 2 :(得分:0)

我不知道你可以在没有阻止的情况下使用content_for(:content_tag),它会返回与使用yield(:content_tag)相同的内容。

所以:

def yield_or_render(content, template)
  content_for?(content) ? content_for(content) : render(template)
end