user1561873
user1561873

Reputation: 33

Rails: unable to escape after using content_for with raw

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

Answers (1)

user1561873
user1561873

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

Related Questions