mirror of
https://gitee.com/openharmony/third_party_jinja2
synced 2024-11-23 15:19:46 +00:00
Ported tojson filter. Fixes #458
This commit is contained in:
parent
ffe0caa1f0
commit
e71a130607
2
CHANGES
2
CHANGES
@ -25,6 +25,8 @@ Version 2.9
|
||||
the string is barely truncated at all.
|
||||
- Change the logic for macro autoescaping to be based on the runtime
|
||||
autoescaping information at call time instead of macro define time.
|
||||
- Ported a modified version of the `tojson` filter from Flask to Jinja2
|
||||
and hooked it up with the new policy framework.
|
||||
|
||||
Version 2.8.2
|
||||
-------------
|
||||
|
12
docs/api.rst
12
docs/api.rst
@ -565,6 +565,18 @@ Example::
|
||||
The default target that is issued for links from the `urlize` filter
|
||||
if no other target is defined by the call explicitly.
|
||||
|
||||
``json.dumps_function``:
|
||||
If this is set to a value other than `None` then the `tojson` filter
|
||||
will dump with this function instead of the default one. Note that
|
||||
this function should accept arbitrary extra arguments which might be
|
||||
passed in the future from the filter. Currently the only argument
|
||||
that might be passed is `indent`. The default dump function is
|
||||
``json.dumps``.
|
||||
|
||||
``json.dumps_kwargs``:
|
||||
Keyword arguments to be passed to the dump function. The default is
|
||||
``{'sort_keys': True}``.
|
||||
|
||||
|
||||
Utilities
|
||||
---------
|
||||
|
@ -41,8 +41,10 @@ DEFAULT_NAMESPACE = {
|
||||
|
||||
# default policies
|
||||
DEFAULT_POLICIES = {
|
||||
'urlize.rel': 'noopener',
|
||||
'urlize.target': None,
|
||||
'urlize.rel': 'noopener',
|
||||
'urlize.target': None,
|
||||
'json.dumps_function': None,
|
||||
'json.dumps_kwargs': {'sort_keys': True},
|
||||
}
|
||||
|
||||
|
||||
|
@ -15,7 +15,7 @@ from random import choice
|
||||
from itertools import groupby
|
||||
from collections import namedtuple
|
||||
from jinja2.utils import Markup, escape, pformat, urlize, soft_unicode, \
|
||||
unicode_urlencode
|
||||
unicode_urlencode, htmlsafe_json_dumps
|
||||
from jinja2.runtime import Undefined
|
||||
from jinja2.exceptions import FilterArgumentError
|
||||
from jinja2._compat import imap, string_types, text_type, iteritems
|
||||
@ -916,6 +916,39 @@ def do_rejectattr(*args, **kwargs):
|
||||
return select_or_reject(args, kwargs, lambda x: not x, True)
|
||||
|
||||
|
||||
@evalcontextfilter
|
||||
def do_tojson(eval_ctx, value, indent=None):
|
||||
"""Dumps a structure to JSON so that it's safe to 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.
|
||||
|
||||
The indent parameter can be used to enable pretty printing. Set it to
|
||||
the number of spaces that the structures should be indented with.
|
||||
|
||||
.. versionadded:: 2.9
|
||||
"""
|
||||
policies = eval_ctx.environment.policies
|
||||
dumper = policies['json.dumps_function']
|
||||
options = policies['json.dumps_kwargs']
|
||||
if indent is not None:
|
||||
options = dict(options)
|
||||
options['indent'] = indent
|
||||
return htmlsafe_json_dumps(value, dumper=dumper, **options)
|
||||
|
||||
|
||||
def prepare_map(args, kwargs):
|
||||
context = args[0]
|
||||
seq = args[1]
|
||||
@ -1021,4 +1054,5 @@ FILTERS = {
|
||||
'wordcount': do_wordcount,
|
||||
'wordwrap': do_wordwrap,
|
||||
'xmlattr': do_xmlattr,
|
||||
'tojson': do_tojson,
|
||||
}
|
||||
|
@ -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."""
|
||||
|
@ -576,3 +576,16 @@ class TestFilter(object):
|
||||
tmpl = env.from_string('{{ users|rejectattr("id", "odd")|'
|
||||
'map(attribute="name")|join("|") }}')
|
||||
assert tmpl.render(users=users) == 'jane'
|
||||
|
||||
def test_json_dump(self):
|
||||
env = Environment(autoescape=True)
|
||||
t = env.from_string('{{ x|tojson }}')
|
||||
assert t.render(x={'foo': 'bar'}) == '{"foo": "bar"}'
|
||||
assert t.render(x='"bar\'') == '"\"bar\u0027"'
|
||||
|
||||
def my_dumps(value, **options):
|
||||
assert options == {'foo': 'bar'}
|
||||
return '42'
|
||||
env.policies['json.dumps_function'] = my_dumps
|
||||
env.policies['json.dumps_kwargs'] = {'foo': 'bar'}
|
||||
assert t.render(x=23) == '42'
|
||||
|
Loading…
Reference in New Issue
Block a user