I have a rails gem that uses a snippet like:
components = []
components << label_for(attribute)
components << ...
components << text_field(attribute)
return components.join
The gem worked fine in Rails 3.0.1, however it escapes (renders as text in a browser) all HTML after updating to Rails 3.0.2. What am I doing something wrong? Thanks.
As @sj26 points out, either use the rails built-in helper:
<%= safe_join(components) %>
Or use my rails_join
gem to make Array#join
html-safe aware, in which case your original code will work as is.
String#join
isn't SafeBuffer
-aware.
String#html_safe
marks that you string is already HTML-escaped, preventing users sneaking bits of HTML into your pages. Check out this post by Yehuda Katz on SafeBuffer
and why/how you should be using them.
If you have an array of String
and SafeBuffer
you want to concatenate, make sure you've run #html_safe
on them all, or #concat
them into a SafeBuffer
like so:
['<one>', '<p>two</p>'.html_safe].inject ''.html_safe, &:concat
=> "<one><p>two</p>"
Rails has a built-in helper called safe_join
which will do this for you.
http://makandra.com/notes/954-don-t-mix-array-join-and-string-html_safe
class Array
def html_safe_join(delimiter='')
''.html_safe.tap do |str|
each_with_index do |element, i|
str << delimiter if i > 0
str << element
end
end
end
end
[safe_string, unsafe_string].html_safe_join(' ')
# '<span>foo</span><span&t;bar</span>'
Strings are automatically HTML-escaped in Rails3. You need to change that last line to:
return components.join.html_safe
alternately, if editing the gem is too much hassle you can do it from the view:
<%= helper_name.html_safe %>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With