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

重要なことは次の 2 つです。

  • content_tagrails は(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 に答える