【问题标题】:yield if content, render something otherwise (Rails 3)产生内容,否则渲染某些东西(Rails 3)
【发布时间】:2011-03-21 19:29:10
【问题描述】:

我已经离开 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作为起点,但它似乎只在直接在视图中使用时才有效。

谢谢!

【问题讨论】:

    标签: ruby-on-rails views rendering


    【解决方案1】:

    这样的事情怎么样?

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

    Inspiration from this SO question

    【讨论】:

    • 看来我会经常使用这种模式,所以我想把它提取到一个助手中。
    【解决方案2】:

    试试这个:

    # 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 %>
    

    【讨论】:

    • 我也问过this question,看看我能不能把这个更简洁。
    • yield_or,正是我需要的。
    【解决方案3】:

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

    所以:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-03-10
      • 2018-05-15
      • 1970-01-01
      • 2011-11-11
      • 1970-01-01
      • 1970-01-01
      • 2020-09-25
      相关资源
      最近更新 更多