method

content_tag

content_tag(name, content_or_options_with_block = nil, options = nil, &block)
public

Returns an HTML block tag of type name surrounding the content. Add <a href="/rails/HTML">HTML</a> attributes by passing an attributes hash to options. For attributes with no value like (disabled and readonly), give it a value of true in the options hash. You can use symbols or strings for the attribute names.

  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>
  content_tag("select", options, :multiple => true)
   # => <select multiple="multiple">...options...</select>

Instead of passing the content as an argument, you can also use a block in which case, you pass your options as the second parameter.

  <% content_tag :div, :class => "strong" do -%>
    Hello world!
  <% end -%>
   # => <div class="strong"><p>Hello world!</p></div>

8Notes

Nil V.S. Empty String HTML Options

newtonapple · Jun 20, 200813 thanks

There is a difference between an empty string and nil value for options hash. ==== Code Sample content_tag( :div, 'Hello World!', :class=>'') # => "

Hello World!
" content_tag( :div, 'Hello World!', :class=>nil) # => "
Hello World!
"

Empty elements

Mange · Feb 17, 20099 thanks

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

Use collect in nested content_tags

nachocab · Jan 27, 20097 thanks

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 #=>

# a # b # c #

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

# abc #

Optional classes

simonmenke · Aug 14, 20086 thanks

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?))

Change to the way the block is handled

CodeFarmer · May 23, 20115 thanks

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
}

Content_tag in helpers

insane-dreamer · Mar 24, 20092 thanks

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.

use #collect instead of #each

lazylester · Feb 15, 2009

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.

Use collect instead of inject/reduce

smgt · Nov 24, 2012

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