[Catalyst] Escaping of "argument" of private path

Octavian Rasnita orasnita at gmail.com
Tue Mar 15 09:56:51 GMT 2011

From: "John M. Dlugosz" <wxju46gefd at snkmail.com>

> On 3/15/2011 1:38 AM, Octavian Rasnita orasnita-at-gmail.com 
> |Catalyst/Allow to home| wrote:
>> uri_for() escapes each component, but I guess that it doesn't escape it 
>> if it contains a slash in it.
>> For example, you can do:
>> <img src="[% c.uri_for('/static', 'ham and eggs.jpg').path %]">
>> It will print:
>> <img src="/static/ham%20and%20eggs.jpg">
>> Octavian
> I see... it wants you to pass separate arguments rather than building the 
> path first.

It just gets the path and the list of arguments, but it escapes the special 
characters only in the arguments, not the path.

> I was thinking that uri_for might be more trouble than it's worth since I 
> don't like fully-qualified URLs in my generated source anyway.  But if it 
> escapes (sometimes?) then that is indeed more helpful.

You don't need to use fully-qualified URLS if you don't like, even though it 
doesn't matter because they are dynamicly generated anyway.
uri_for() returns a URI object, so you can use:


This will return only the path, without the scheme, host and port.



...if the URL also contains a query string (?a=b&c=d)

> <img src="[% c.uri_for("/static/gallery",rec.dirname,rec.filename) %]" 
> alt="photo" />
> That works (using Smart_URI settings to leave off the host).  But it did 
> not escape out the '&' in the filename!  Is that a bug?  I notice you 
> changes my example from '&' to 'and' -- that's cheating!


> <img src="[% "/static/gallery/${rec.dirname}/${ rec.filename | uri }" %]" 
> alt="photo" />
> gives the correct answer: ham%20%26%20eggs.jpeg

uri_for() escapes only the chars which are not in the following list (from 

$reserved   = q(;/?:@&=+$,[]);
$mark       = q(-_.!~*'());                                    #'; emacs
$unreserved = "A-Za-z0-9\Q$mark\E";

The char "&" is a valid char in the URI, so it should not be escaped.. With 
other words, the following url is OK:


uri_for() generates the URI as it needs to be accessed on the server and not 
as it should be printed in an HTML page. In order to be printed correctly, 
the "&" char must be HTML-encoded, so the html TT filter must be used:

<a href="[% c.uri_for('/path', 'eggs & ham.jpg', {a=1, b=2}).path_query | 

It will give:

<a href="/path/eggs%20&amp;%20ham.jpg?a=1&amp;b=2">label</a>


More information about the Catalyst mailing list