I'm running into an issue with the rails auto-escaping. It currently thinks a string is html_safe (which it is), but for display purposes I need it to still escape the html. Here's the steps the string is taking.
my_string = render(:partial => "set_string", :locals => {:item => @item})
<%= my_string %>
and the partial is basically
<h2>Page Header</h2>
<strong><%= item.name %></strong>
<%= item.body %>
etc
My understanding is that because I'm displaying text in a view directly (the h2, etc) it assumes it is safe, and it also properly escapes the item outputs, which makes the whole my_string safe. So, when I try to display it with the
<%= my_string %>
It doesn't escape the remaining html. I tried adding h to force the escaping but that didn't work.
So my question is, is there anyway to force html escaping of a safe string other than calling something on the string that will make it unsafe?
Thanks a lot for your help.
Thanks to Sebastien for the suggestion, I wanted to get the real answer here and not buried in the comments:
I looks like this works:
You need the "raw" call otherwise the escapeHTML makes the string unsafe in addition to escaping it so the auto escape double escapes it.
Escape from ActiveSupport::SafeBuffer in Rails 3+
In this instance
<%= my_string.to_str %>
will double-escape as required.SafeBuffer workings
When a string is escaped by Rails you get an
ActiveSupport::SafeBuffer
. From that point, extra escaping is skipped because theSafeBuffer
ishtml_safe?
. It's a clever solution! There are times though, that we wish to escape such cleverness.Why double-escape?
I needed to re-escape content generated by tag helpers to pass generated markup to
data-
attributes. This has also come in handy for displaying template-generated code.Force-escape for a
String
that'shtml_safe?
Call
to_str
on theSafeBuffer
, which returns aString
.The
to_s
gotchaThe
to_s
method looks very much like theto_str
method. Don't useto_s
here,ActionView::SafeBuffer#to_s
just returnsself
, whereto_str
is called above theSafeBuffer
context, returning a naturally unsafeString
.To interpret the html (it's what i understood you need), you have to use :