advertised.
- Fixed filesizeformat.
- Added a non-silent option for babel extraction.
+- Added `urlescape` filter that automatically quotes values for
+ URL safe usage with utf-8 as only supported encoding. If applications
+ want to change this encoding they can override the filter.
Version 2.6
-----------
"""
import re
import math
-import urllib
from random import choice
from operator import itemgetter
from itertools import imap, groupby
-from jinja2.utils import Markup, escape, pformat, urlize, soft_unicode
+from jinja2.utils import Markup, escape, pformat, urlize, soft_unicode, \
+ unicode_urlescape
from jinja2.runtime import Undefined
from jinja2.exceptions import FilterArgumentError
def do_urlescape(value):
- """Escape strings for use in URLs (uses UTF-8 encoding)."""
- def utf8(o):
- return unicode(o).encode('utf8')
+ """Escape strings for use in URLs (uses UTF-8 encoding). It accepts both
+ dictionaries and regular strings as well as pairwise iterables.
- 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)
+ .. versionadded:: 2.7
+ """
+ itemiter = None
+ if isinstance(value, dict):
+ itemiter = value.iteritems()
+ elif not isinstance(value, basestring):
+ try:
+ itemiter = iter(value)
+ except TypeError:
+ pass
+ if itemiter is None:
+ return unicode_urlescape(value)
+ return u'&'.join(unicode_urlescape(k) + '=' +
+ unicode_urlescape(v) for k, v in itemiter)
@evalcontextfilter
assert tmpl.render() == '<div>foo</div>'
tmpl = env.from_string('{{ "<div>foo</div>" }}')
assert tmpl.render() == '<div>foo</div>'
-
+
def test_urlescape(self):
env = Environment(autoescape=True)
tmpl = env.from_string('{{ "Hello, world!"|urlescape }}')
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"
+ assert tmpl.render(o={0: 1}) == "0=1"
+
def suite():
suite = unittest.TestSuite()
import re
import sys
import errno
+try:
+ from urllib.parse import quote_from_bytes as url_quote
+except ImportError:
+ from urllib import quote as url_quote
try:
from thread import allocate_lock
except ImportError:
return Markup(u'\n'.join(u'<p>%s</p>' % escape(x) for x in result))
+def unicode_urlescape(obj, charset='utf-8'):
+ """URL escapes a single bytestring or unicode string with the
+ given charset if applicable to URL safe quoting under all rules
+ that need to be considered under all supported Python versions.
+
+ If non strings are provided they are converted to their unicode
+ representation first.
+ """
+ if not isinstance(obj, basestring):
+ obj = unicode(obj)
+ if isinstance(obj, unicode):
+ obj = obj.encode(charset)
+ return unicode(url_quote(obj))
+
+
class LRUCache(object):
"""A simple LRU Cache implementation."""