Agile Tortoise

Greg Pierce’s blog

« Dallas.rb, now with Dave Thomas!      Free acoustic guitar ringtones »

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

Thursday, March 1st, 2007 at 9:44 pm and is filed under Ruby on Rails. You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.

7 Responses to “Rails: content_tag block fix”

  1. Jordan Says:
    March 15th, 2007 at 12:50 pm

    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. greg Says:
    March 16th, 2007 at 8:56 pm

    If you want to build HTML like that, you should look at Markaby.

    g.

  3. oscar Says:
    March 17th, 2007 at 10:35 pm

    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>

  4. oscar Says:
    March 17th, 2007 at 10:43 pm

    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)

  5. gustin Says:
    September 13th, 2007 at 8:26 pm

    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

  6. Mario Lanza Says:
    February 16th, 2008 at 11:05 am

    Saved me too. Thanks.

  7. Salman Ansari Says:
    March 25th, 2008 at 4:28 pm

    Awesome dude, this just saved me some effort :)

    Keep up the good work! Thanks.

Leave a Reply