url_for always escape string.

according to the documentation, only the url_for from ActionView escape the URL. which happens on this line

escape ? html_escape(url) : url

and can be prevented by passing :escape => false to url_for. still according to the documentation, the url_for from ActionController is not supposed to escape the url.

BUT IT DOES.

at the moment of this line

escape ? html_escape(url) : url

url has already been escaped by the url_for from action_controller thus the option :escape is irrelevant.

I believe someone change something without knowing this.

the url_for from the controller is not suppose to escape the url while it does. and the :escape => false just prevent the url from being escaped AGAIN.

I went a bit into the code, as far as Routing::Routes.generate so it get escaped somewhere in there. That's as far as I check

regards,

somekool wrote:

according to the documentation, only the url_for from ActionView escape the URL.

<snip>

still according to the documentation, the url_for from ActionController is not supposed to escape the url. BUT IT DOES.

Where have you seen the double-escaping behaviour? I've found some problems with some of the form-related helpers where URLs are double-escaped, but the problem is in the helpers, not in ActionController's url_for.

Can you give us some example code that shows this escaping happening?

Chris

Lets clarify what I said. The url is escaped twice, but the output is the same.

it changes a quote for example into %xx but the second time, it remains %xx unchanged, cuz its ok

lets look at the function

      def url_for(options = {}, *parameters_for_method_reference)         if options.kind_of? Hash           options = { :only_path => true }.update(options.symbolize_keys)           escape = options.key?(:escape) ? options.delete(:escape) : true         else           escape = true         end         url = @controller.send(:url_for, options, *parameters_for_method_reference)         escape ? html_escape(url) : url       end

most of this function is related to check if :escape => false is passed, in which case html_escape won't be call. but before this last line, url already been escaped. so its not possible to prevent url_for from escaping the URL anymore. and at this point. providing this option does nothing

but the value returned by html_escape will be the same as the value url already has. so it does not get really escaped twice. but the string is going into the machine twice, if you see what I mean.

somekool wrote:

it changes a quote for example into %xx but the second time, it remains %xx unchanged, cuz its ok

I think this is where the confusion is arising. There are two different kinds of escaping going on.

It sounds like you're talking about the URL encoding that uses '%xx' to represent special characters.

However, the html_escape function does something completely different. It takes a string and turns '&' into '&amp;' and '<' into '&lt;', etc., so that it can go into HTML without being interpreted as literal '&'s and '<'s.

Escaping special characters in URLs using the '%xx' scheme is mandatory, otherwise they are not valid URLs.

But HTML-escaping using '&' can be turned off using the :escape => false option. Of course, you always want to HTML-escape the URL at some point before outputting it in HTML. And most of the time it's okay to let url_for do this for you. But sometimes you need to take the result of url_for and pass it through another function that does its own HTML-escaping. That's when you can make use of the :escape => false option to url_for.

Chris

thank you for the enlightenment, it does clarify bunch of things

the reason I need the URL encoding not to be done, is because I pass the url_for results to javascript code, and some part of the url is javascript that gets evaluated to then become a valid URI.

so I decided to do something like this url_for(:action => 'foo', :id => '__js__').gsub('__js__', js)

which works like I want, but I thought I could just pass an option to url_for instead of the gsub