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):
'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
}
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&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()