If you, like me, have tried to use helpers to generate complex chunks of HTML
programmaticly, then you will have noticed that content_tag
doesn’t really
cut it for large chunks of HTML
content_tag
will render the HTML inline unless you manually insert line
breaks and tabs in order to make it readable, not to mention you end up with a
horribly nested set of methods wrapping around the content you want to display
Looking something a little like this
def render_user_status
if user_signed_in?
inner_html = content_tag(:span, "Signed in as #{current_user.email}. Not you? \n #{link_to("Sign out", destroy_user_session_path)}")
else
inner_html = content_tag(:span, "#{link_to("Sign up", new_user_registration_path)} \n or \n #{link_to("Sign in", new_user_session_path)}")
end
return content_tag(:div, inner_html, :id => "user_nav")
end
As you can see the code looks quite unreadable, and it’s almost backwards in the way that it is generated, I’m creating the inner HTML first, and then wrapping it inside a div depending on if the user is logged in or not, there must be a better way to achieve the same result, while making it look nicer
The builder gem is something that I have used most often for defining XML documents, however you can also call the Builder::XmlMarkup.new method within any other methods and generate XML markup inline. Using the same example, this is the execution using Builder::XmlMarkup instead of content_tag
def render_user_status
xhtml = Builder::XmlMarkup.new :target => out=(''), :indent => 2
xhtml.div(:id => "user_nav") do |x|
if user_signed_in?
x << "Signed in as #{current_user.email}. Not you? "
x << link_to("Sign out", destroy_user_session_path)
else
x << link_to("Sign up", new_user_registration_path)
x << " or "
x << link_to("Sign in", new_user_session_path)
end
end
end
As you can see it’s much more readable than the previous example
However each to their own, but I think personally the Builder gem is incredibly useful for creating XML style markup instead of using Rails’ built in helpers to generate HTML. Give it a go, you might be pleasantly surprised!