Flowdock
content_tag(name, content, options = nil) public

Examples:

  • content_tag("p", "Hello world!") => <p>Hello world!</p>
  • content_tag("div", content_tag("p", "Hello world!"), "class" => "strong") => <div class="strong"><p>Hello world!</p></div>
Show source
Register or log in to add new notes.
June 20, 2008
13 thanks

Nil V.S. Empty String HTML Options

There is a difference between an empty string and nil value for options hash.

Code Sample

content_tag( :div, 'Hello World!', :class=>'') # => "<div class="">Hello World!</div>"
content_tag( :div, 'Hello World!', :class=>nil) # => "<div>Hello World!</div>"
February 17, 2009
9 thanks

Empty elements

If you want to output an empty element (self-closed) like “br”, “img” or “input”, use the tag method instead.

August 14, 2008
5 thanks

Optional classes

This piece of syntax saves me allot of time. Note the if statement.

Code example

content_tag(:div, "Hello World", :class => ("active" if i_am_an_active_item?))
May 23, 2011 - (>= v3.0.5)
5 thanks

Change to the way the block is handled

At least in 3.0.5, some of the previous examples no longer work: ActionView seems to quietly ignore Array content.

If you were using code of the form

content_tag(:li, nil, :class => 'someClass') {
  arr.collect { |x|
    content_tag(:ul, x)
  }
}

it now needs to look like

content_tag(:li, nil, :class => 'someClass') {
  arr.reduce('') { |c, x|
    c << content_tag(:ul, x)
  }.html_safe
}
January 27, 2009
5 thanks

Use collect in nested content_tags

Remember to use #collect instead of #each in nested content_tags

arr = ['a','b','c']
content_tag :div do 
  arr.collect { |letter| content_tag(:scan, letter) 
end
#=> <div>
#      <scan>a</scan>
#      <scan>b</scan>
#      <scan>c</scan>
#   </div>

If you used #each you would get this (which is probably a mistake):

#=> <div>
#      abc
#   </div>
March 24, 2009
1 thank

Content_tag in helpers

Content_tag works great in a helper and is a nice way to clean up your views.

If you’re returning more than one content_tag you’ll need to concat them:

@content = content_tag(:tr, "first item")
@content << content_tag(:tr, "second item")

Be mindful that when doing the above, you must use parentheses around the content_tag options. In the above example, content_tag :tr, “second item” will return an error.

February 15, 2009
0 thanks

use #collect instead of #each

The earlier reminder to use #collect instead of #each applies regardless of whether the tag is nested or not.

This is counterintuitive, as #collect returns an array of strings of HTML tags, but ActionView renders it properly.

November 24, 2012 - (v3.0.5 - v3.2.8)
0 thanks

Use collect instead of inject/reduce

You can still use collect when you nest content_tag . Just join the collection in the end and remember to add html_safe if you don’t want your html to be escaped.

a = ['a','b','c']
content_tag(:ul, :class => 'a class') do
  a.collect do |item|
    content_tag(:li, item)
  end.join.html_safe
end
April 2, 2013 - (v3.0.0 - v3.2.13)
0 thanks

Use concat insted of joining collection explicitely

concat method will be useful to join the collection object from looping conditions.

arr = ["a", "b", "c"]
content_tag(:ul, :class => 'a class') do
  arr.each do |item|
  concat content_tag(:li, item)
end

And this will generate the html as shown below

<ul class="a class">
  <li>a</li>
  <li>b</li>
  <li>c</li>
</ul>