live up to @mitsuhiko's ridiculous expectations
authorAaron Swartz <me@aaronsw.com>
Sat, 7 Jan 2012 01:25:57 +0000 (20:25 -0500)
committerAaron Swartz <me@aaronsw.com>
Sat, 7 Jan 2012 01:25:57 +0000 (20:25 -0500)
jinja2/filters.py
jinja2/testsuite/filters.py

index c170f510f2a9fcda735af577b7a34b89706e4154..69e67e2913974f6fe7a3f5d088d2c266bcc8de21 100644 (file)
@@ -71,8 +71,22 @@ def do_forceescape(value):
     return escape(unicode(value))
 
 def do_urlescape(value):
-    """Escape for use in URLs."""
-    return urllib.quote(value.encode('utf8'))
+    """Escape strings for use in URLs (uses UTF-8 encoding)."""
+    def utf8(o):
+        return unicode(o).encode('utf8')
+    
+    if isinstance(value, basestring):
+        return urllib.quote(utf8(value))
+    
+    if hasattr(value, 'items'):
+        # convert dictionaries to list of 2-tuples
+        value = value.items()
+    
+    if hasattr(value, 'next'):
+        # convert generators to list
+        value = list(value)
+    
+    return urllib.urlencode([(utf8(k), utf8(v)) for (k, v) in value])
 
 @evalcontextfilter
 def do_replace(eval_ctx, s, old, new, count=None):
@@ -802,8 +816,5 @@ FILTERS = {
     'groupby':              do_groupby,
     'safe':                 do_mark_safe,
     'xmlattr':              do_xmlattr,
-    'urlescape':            do_urlescape,
-    'urle':                 do_urlescape,
-    'urlencode':            do_urlescape,
-    'urlquote':             do_urlescape
+    'urlescape':            do_urlescape
 }
index a75129974a10ae2d6a32f5f2cb1a825927f6087d..59795be47ced2637153a2f5786534433fcbca4c6 100644 (file)
@@ -369,8 +369,14 @@ class FilterTestCase(JinjaTestCase):
     
     def test_urlescape(self):
         env = Environment(autoescape=True)
-        tmpl = env.from_string('{{ "Hello, world!"|urle }}')
+        tmpl = env.from_string('{{ "Hello, world!"|urlescape }}')
         assert tmpl.render() == 'Hello%2C%20world%21'
+        tmpl = env.from_string('{{ o|urlescape }}')
+        assert tmpl.render(o=u"Hello, world\u203d") == "Hello%2C%20world%E2%80%BD"
+        assert tmpl.render(o=(("f", 1),)) == "f=1"
+        assert tmpl.render(o=(('f', 1), ("z", 2))) == "f=1&amp;z=2"
+        assert tmpl.render(o=((u"\u203d", 1),)) == "%E2%80%BD=1"
+        assert tmpl.render(o={u"\u203d": 1}) == "%E2%80%BD=1"
 
 def suite():
     suite = unittest.TestSuite()