Rails: content_tag block fix

Currently (as of 1.2.2), Ruby on Rails useful content_tag method fails if you try to pass a block to it in code. The following syntax works in a view template:

RUBY:
  1. <% content_for('div') do %>
  2. this is the <b>div content&lt;/b>.
  3. <% end %>

But, if you try to do the equivalent in ruby code (like in a helper), such as the below, it tanks:

RUBY:
  1. content_for('div') do
  2.    'this is the &lt;b>div content&lt;/b>'
  3. end

While I'm far from an expert on Ruby details, I did a little re-write of the method. If you drop the following in your application_helper (or other place of your choice) you'll get a fully functional version:

RUBY:
  1. def content_tag(name, content_or_options_with_block = nil, options = nil, &block)
  2.     if block_given?
  3.       options = content_or_options_with_block if content_or_options_with_block.is_a?(Hash)
  4.       content = block.call
  5.     else
  6.       content = content_or_options_with_block
  7.     end
  8.     content_tag_string(name, content, options)
  9.   end

8 responses to “Rails: content_tag block fix”

  1. Jordan

    Thanks for this fix – I just ran into the same problem.

    I wonder if it could be tweaked a little more. I wrote up an explanation here http://www.ruby-forum.com/topic/101460 I’d really like to help out, but my Ruby skills are a bit lacking.

  2. oscar

    1- Do you have an example of where do you put exactly the new definition of contag_tag.

    I’ve tried but got:
    private method `content_tag_string’ called for #:0xb781d20c>

  3. oscar

    Actually just after posting my question I find a better solution.

    There is no need to overide content_tag. In your code you can just write :
    content_tag(name, capture(&block), options)

  4. gustin

    thanks!
    i was excited to clean up my helpers with content_tag, but ran into this very problem.

    oscar, it is all about aesthetics — isn’t that why we all love ruby ;-P
    anything non-trivial is way nicer looking like this:

    cell += content_tag :tr do
    content_tag :td do
    “hello world”
    end
    end

    apply this to more complicated tabular data your spitting out in a view helper, seems beneficial

  5. Mario Lanza

    Saved me too. Thanks.

  6. Salman Ansari

    Awesome dude, this just saved me some effort :)

    Keep up the good work! Thanks.

  7. Wil Alvarez

    Thanks for that fix! You save me from madness xD

    Way to go

Leave a Reply

Switch to our mobile site