Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to output html_safe within <%=%> block while concatenating strings?

Consider this:

<%
str = "http://domain.com/?foo=1&bar=2"
%>

Now these cases:

<%=str%>
# output:http://domain.com/?foo=1&amp;bar=2

<%=str.html_safe%>
# output:http://domain.com/?foo=1&bar=2

<%="#{str.html_safe}"%>
# output:http://domain.com/?foo=1&amp;bar=2

<%=""+str.html_safe%>
# output:http://domain.com/?foo=1&amp;bar=2

I need to output the URL with other strings. How can I guarantee that the ampersand will be unescaped? For reasons beyond my control I can't send &amp;.

Please help! Pulling my hair here :\

EDIT: To clarify, I actually have an array like so:

@images = [{:id=>"fooid",:url=>"http://domain.com/?foo=1&bar=2"},...]

I am creating a JS array (the image_array var) to use in my app this way:

image_array.push(<%[email protected]{|x|"{id:'#{x[:id]}',url:'#{x[:url].html_safe}'}"}.join(",")%>);

This generates:

image_array.push({id:'fooid',url:'http://domain.com/?foo=1&amp;bar=2'},...);

Which does not work in my specific case. I need the url without the amp; part.

like image 409
mga Avatar asked Apr 19 '12 16:04

mga


2 Answers

When you write:

"#{foo.bar}"

this is ~equivalent to writing

foo.bar.to_s

So what you are actually doing is:

<%=str.html_safe.to_s%>

…which Rails no longer sees as being safe, and so it hits your resulting string with a round of HTML escaping.

I don't know the internals of Rails, but I assume that the html_safe method extends the string object with an instance variable flagging it as OK, but when you wrap that in another string via interpolation you are getting a new string without that flag.

Edit: To answer your needs, use raw or call html_safe on your final string:

<%=raw "foo#{str}"%>
<%="foo#{str}".html_safe%>

or in your case:

image_array.push(<%=raw @images.map{…}.join(',')%>);
image_array.push(<%[email protected]{…}.join(',').html_safe%>);

See also this question.

like image 156
Phrogz Avatar answered Sep 19 '22 23:09

Phrogz


Use this

    <%=str.html_safe.to_s%>

or

   <%=raw(str)%>   

give you better results

like image 34
Kashiftufail Avatar answered Sep 17 '22 23:09

Kashiftufail