Reputation: 33
In a helper method I have this:
content_for(:title, raw(page_title))
And in my view I have this after calling the helper method:
<%= h(content_for(:title)) %>
However when I do this, the h() does not HTML escape the content? I've also tried content_for(:title).html_safe
and html_escape(content_for(:title))
with no success.
I save the content as raw as I want to access the raw (unescaped) content in a separate view. I'm on Rails 3.0.17.
Upvotes: 1
Views: 843
Reputation: 33
After some investigation, here's my conclusions: It's all about html_safe.
Let me explain with some code:
page_title.html_safe? #false
raw(page_title).html_safe? #true - that's all that raw does
content_for(:title, raw(page_title)) #associates :title with page_title, where page_title.html_safe? returns true
Now when the view calls the helper method here's what happens:
content_for(:title) #no escaping. Since page_title was stored and html_safe is true, conetnt_for will not escape
h(content_for(:title)) #no escaping. Since the last line returned a string where html_safe? returns true, this will also not escape.
<%= h(content_for(:title)) %> #no escaping. Same reason as above
In short, raw
simply sets the html_safe
attribute on the string/SafeBuffer. Escaping is performed only on strings where string.html_safe?
returns false
. Since the string returns true
at each opportunity for escaping, the string is never escaped.
Resolution:
Create a new string through interpolation or concatenation - this will set html_safe to false again and the string will be escaped.
For more, check out this guide on SafeBuffers and read the docs.
Upvotes: 1