EricLarch
EricLarch

Reputation: 5773

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

Upvotes: 8

Views: 2803

Answers (2)

Amiel Martin
Amiel Martin

Reputation: 4814

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)) %>

Upvotes: 1

tehprofessor
tehprofessor

Reputation: 3013

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

Upvotes: 6

Related Questions