Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why are ampersands escaped when generating url with link_to?

Here is my simple rails 3 code :

<%= link_to "link", gateway_index_url(developer:@item.developer.api_key, tracker:"email", url:@product.url) %>

And the result is :

<a href="/gateway?developer=abcde&amp;tracker=email&amp;url=http%3A%2F%2Fwww.bla.fr%2FproductA" >link</a>

The problem is that & are rewritten in &amp;. I can't figure how to prevent escaping, as :escape => false doesn't exist in Rails 3

like image 675
EricLarch Avatar asked Aug 22 '13 17:08

EricLarch


People also ask

How do I allow ampersand in URL?

For example, to encode a URL with an ampersand character, use %26. However, in HTML, use either & or &, both of which would write out the ampersand in the HTML page.

How do you escape ampersand in query string?

To escape Ampersand in JavaScript, use encodeURIComponent() in JavaScript. As you can see that when we called encodeURIComponent , it encoded & to %26 . You can use % to escape characters that aren't allowed in URLs. Here & is 26 in Hexadecimal and that's the reason encodeURIComponent() converted & to %26 .


2 Answers

Update: So here's the source

  def link_to(*args, &block)
    if block_given?
      options      = args.first || {}
      html_options = args.second
      link_to(capture(&block), options, html_options)
    else
      name         = args[0]
      options      = args[1] || {}
      html_options = args[2]

      html_options = convert_options_to_data_attributes(options, html_options)
      url = url_for(options)

      href = html_options['href']
      tag_options = tag_options(html_options)

      href_attr = "href=\"#{ERB::Util.html_escape(url)}\"" unless href
      "<a #{href_attr}#{tag_options}>#{ERB::Util.html_escape(name || url)}</a>".html_safe
    end
  end

As we can see, from the source, this behavior is by design.

You can try one of two solutions, I haven't tried them but they should work

1.) Try placing the call to gateway inside of a call to #raw:

<%= link_to "link", raw(gateway_index_url(developer: @item.developer.api_key, tracker:"email", url:@product.url)) %>

That may solve your specific problem, an the second approach, while a bit more brute-force should also work...

2.) If you want to convert it (the whole href) back you can... use CGI::unescape_html:

<%= CGI::unescape_html(link_to "link", gateway_index_url(developer: @item.developer.api_key, tracker:"email", url:@product.url)) %>

Good luck, hopefully this helps.

Update 2: Fixed call to cgi unescape, was using "." when it should be "::" and formatting fix. Forgot to indent example for #1

like image 116
tehprofessor Avatar answered Nov 02 '22 23:11

tehprofessor


Rory O'Kane is spot on. The answer to "Why are ampersands escaped when generating url with link_to?" is that is the correct way to separate params in a url.

Is there a problem with the url the way it is? If so, could you elaborate on the problem?

You may be able to prevent escaping the url by using raw on the entire url like so:

<%= link_to "link", raw(gateway_index_url(developer:@item.developer.api_key, tracker:"email", url:@product.url)) %>
like image 20
Amiel Martin Avatar answered Nov 03 '22 01:11

Amiel Martin