method

content_tag

content_tag(name, content_or_options_with_block = nil, options = nil, escape = true, &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. 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. Set escape to false to disable attribute value escaping.

Options

The options hash is used with attributes with no value like (disabled and readonly), which you can give a value of true in the options hash. You can use symbols or strings for the attribute names.

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

  <% content_tag :div, :class => "strong" do -%>
    Hello world!
  <% end -%>
   # => <div class="strong">Hello world!</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