14

我想做一个像下面这样的助手。

def my_div some_options, &block
  # 如何打印块的结果?
结尾
4

3 回答 3

23

您应该使用CaptureHelper

def my_div(some_options, &block)
  # capture the value of the block a string
  content = capture(&block)
  # concat the value to the output
  concat(content)
end

<% my_div([]) do %>
  <p>The content</p>
<% end %>


def my_div(some_options, &block)
  # capture the value of the block a string
  # and returns it. You MUST use <%= in your view.
  capture(&block)
end

<%= my_div([]) do %>
  <p>The content</p>
<% end %>

如果需要连接输出,请使用 capture + concat。如果您需要捕获然后重用内容,请使用捕获。如果您的块没有明确使用 <%=,那么您必须调用 concat (首选方式)。

如果用户不是管理员,这是隐藏内容的方法示例。

def if_admin(options = {}, &block)
  if admin?
    concat content_tag(:div, capture(&block), options)
  end
end

<% if_admin(:style => "admin") do %>
<p>Super secret content.</p>
<% end %>
于 2009-06-26T09:27:28.617 回答
2

所以有两件事很重要:

  • content_tagrails 忽略 a (and content_for)中不是字符串的任何内容
  • 你不能使用Array#join(等),因为它会产生不安全的字符串,你需要使用safe_joincontent_tag拥有安全的字符串
  • 我不需要,capture或者concat在我的情况下。
  def map_join(objects, &block)
    safe_join(objects.map(&block))
  end

  def list(objects, &block)
    if objects.none?
      content_tag(:p, "none")
    else
      content_tag(:ul, class: "disc") do
        map_join(objects) do |object|
          content_tag(:li) do
            block.call(object)
          end
        end
      end
    end
  end

这可以像这样使用:

= list(@users) do |user|
  => render user
  = link_to "show", user 

(这很苗条,但也适用于 erb)

于 2019-05-01T08:22:01.137 回答
1

http://www.rubycentral.com/book/tut_containers.html

yield 语句将返回传递的块的结果。所以如果你想打印(控制台?)

def my_div &block
  yield
end

my_div { puts "Something" } 

会输出“某事”

但是:你的方法的想法是什么?输出一个DIV?

于 2009-06-26T09:14:26.660 回答