content_tag
content_tag(name, content_or_options_with_block = nil, options = nil, escape = true, &block)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
There is a difference between an empty string and nil value for options hash. ==== Code Sample content_tag( :div, 'Hello World!', :class=>'') # => "
Empty elements
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
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 #=>
If you used #each you would get this (which is probably a mistake): #=>
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?))
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
}
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.
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.
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