Block usage of content_tag

Arnaud take a look at the Rails source for content_tag: http://pastie.caboo.se/80983

      def content_tag(name, content_or_options_with_block = nil,
options = nil, &block)
        if block_given?
          options = content_or_options_with_block if
content_or_options_with_block.is_a?(Hash)
          content = capture(&block)
          concat(content_tag_string(name, content, options),
block.binding)
        else
          content = content_or_options_with_block
          content_tag_string(name, content, options)
        end
      end

If you give it a block, it calls concat(content_tag_string(name,
content, options), block.binding).

module StoreHelper

  def hidden_div_if(condition, attributes = {})
    if condition
      attributes["style" ] = "display: none"
    end
    content_tag("div" , attributes) {yield}
  end

...

If you use content_tag("div" , attributes) {yield} inside your
hidden_div_if(), when concat inside content_tag() will be called w/
the binding of you block: {yield}, which has the StoreHelper's context
as to your View's context: (the original block passed in
hidden_div_if). As a result, when concat() gets called inside
content_tag, it doesn't have the right binding and hence missing:
"_erbout." I hope this helps. :slight_smile:

David Dai wrote:

Arnaud take a look at the Rails source for content_tag: http://pastie.caboo.se/80983

     def content_tag(name, content_or_options_with_block = nil,
options = nil, &block)
       if block_given?
         options = content_or_options_with_block if
content_or_options_with_block.is_a?(Hash)
         content = capture(&block)
         concat(content_tag_string(name, content, options),
block.binding)
       else
         content = content_or_options_with_block
         content_tag_string(name, content, options)
       end
     end

If you give it a block, it calls concat(content_tag_string(name,
content, options), block.binding).

module StoreHelper

  def hidden_div_if(condition, attributes = {})
    if condition
      attributes["style" ] = "display: none"
    end
    content_tag("div" , attributes) {yield}
  end

...

If you use content_tag("div" , attributes) {yield} inside your
hidden_div_if(), when concat inside content_tag() will be called w/
the binding of you block: {yield}, which has the StoreHelper's context
as to your View's context: (the original block passed in
hidden_div_if). As a result, when concat() gets called inside
content_tag, it doesn't have the right binding and hence missing:
"_erbout." I hope this helps. :slight_smile:

Thanks - that confirms what I implied, when I was too lazy to look up the actual method!

The best way to use capture{} is don't, guys! (-;