diff options
Diffstat (limited to 'jinja2/utils.py')
-rw-r--r-- | jinja2/utils.py | 31 |
1 files changed, 31 insertions, 0 deletions
diff --git a/jinja2/utils.py b/jinja2/utils.py index 96b13521..38e5edb2 100644 --- a/jinja2/utils.py +++ b/jinja2/utils.py @@ -9,6 +9,7 @@ :license: BSD, see LICENSE for more details. """ import re +import json import errno from collections import deque from threading import Lock @@ -37,6 +38,8 @@ internal_code = set() concat = u''.join +_slash_escape = '\\/' not in json.dumps('/') + def contextfunction(f): """This decorator can be used to mark a function or method context callable. @@ -485,6 +488,34 @@ except ImportError: pass +def htmlsafe_json_dumps(obj, dumper=None, **kwargs): + """Works exactly like :func:`dumps` but is safe for use in ``<script>`` + tags. It accepts the same arguments and returns a JSON string. Note that + this is available in templates through the ``|tojson`` filter which will + also mark the result as safe. Due to how this function escapes certain + characters this is safe even if used outside of ``<script>`` tags. + + The following characters are escaped in strings: + + - ``<`` + - ``>`` + - ``&`` + - ``'`` + + This makes it safe to embed such strings in any place in HTML with the + notable exception of double quoted attributes. In that case single + quote your attributes or HTML escape it in addition. + """ + if dumper is None: + dumper = json.dumps + rv = dumper(obj, **kwargs) \ + .replace(u'<', u'\\u003c') \ + .replace(u'>', u'\\u003e') \ + .replace(u'&', u'\\u0026') \ + .replace(u"'", u'\\u0027') + return rv + + @implements_iterator class Cycler(object): """A cycle helper for templates.""" |