Skip to content

Commit 5b38019

Browse files
author
Nicole Thomas
authored
Merge pull request #48339 from terminalmage/backport-tojson-filter
Backport tojson filter from #48309 to 2018.3
2 parents 222c1d6 + 4433bec commit 5b38019

File tree

6 files changed

+88
-2
lines changed

6 files changed

+88
-2
lines changed

doc/topics/jinja/index.rst

+23
Original file line numberDiff line numberDiff line change
@@ -886,6 +886,10 @@ Example:
886886
encoding (usually a ``unicode`` type). This filter was incorrectly-named
887887
when it was added. ``json_decode_list`` will be supported until the Neon
888888
release.
889+
.. deprecated:: 2018.3.3,Fluorine
890+
The :jinja_ref:`tojson` filter accomplishes what this filter was designed
891+
to do, making this filter redundant.
892+
889893

890894
Recursively encodes all string elements of the list to bytes.
891895

@@ -915,6 +919,9 @@ Returns:
915919
encoding (usually a ``unicode`` type). This filter was incorrectly-named
916920
when it was added. ``json_decode_dict`` will be supported until the Neon
917921
release.
922+
.. deprecated:: 2018.3.3,Fluorine
923+
The :jinja_ref:`tojson` filter accomplishes what this filter was designed
924+
to do, making this filter redundant.
918925

919926
Recursively encodes all string items in the dictionary to bytes.
920927

@@ -934,6 +941,22 @@ Returns:
934941
{'a': '\xd0\x94'}
935942
936943
944+
.. jinja_ref:: tojson
945+
946+
``tojson``
947+
----------
948+
949+
.. versionadded:: 2018.3.3,Fluorine
950+
951+
Dumps a data structure to JSON.
952+
953+
This filter was added to provide this functionality to hosts which have a
954+
Jinja release older than version 2.9 installed. If Jinja 2.9 or newer is
955+
installed, then the upstream version of the filter will be used. See the
956+
`upstream docs`__ for more information.
957+
958+
.. __: http://jinja.pocoo.org/docs/2.10/templates/#tojson
959+
937960
.. jinja_ref:: random_hash
938961

939962
``random_hash``

doc/topics/releases/2018.3.3.rst

+17
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,20 @@ Improves timezone detection by using the pytz module.
1414

1515
Adds ``timezone.list`` to list supported timezones in either Windows or Unix
1616
format.
17+
18+
New Jinja Filter
19+
================
20+
21+
The :jinja_ref:`tojson` filter (from Jinja 2.9 and later) has been ported to
22+
Salt, and will be used when this filter is not available. This allows older LTS
23+
releases such as CentOS 7 and Ubuntu 14.04 to use this filter.
24+
25+
You should use this filter any time you wish to dump a list or dictionary into
26+
an SLS file, to ensure that the result is able to be loaded by the YAML
27+
renderer. For example:
28+
29+
.. code-block:: jinja
30+
31+
foo:
32+
bar.baz:
33+
- some_arg: {{ mydict|tojson }}

salt/utils/data.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,7 @@ def encode(data, encoding=None, errors='strict', keep=False,
274274

275275

276276
@jinja_filter('json_decode_dict') # Remove this for Neon
277-
@jinja_filter('json_encode_dict')
277+
@jinja_filter('json_encode_dict') # Remove this for Neon
278278
def encode_dict(data, encoding=None, errors='strict', keep=False,
279279
preserve_dict_class=False, preserve_tuples=False):
280280
'''
@@ -327,7 +327,7 @@ def encode_dict(data, encoding=None, errors='strict', keep=False,
327327

328328

329329
@jinja_filter('json_decode_list') # Remove this for Neon
330-
@jinja_filter('json_encode_list')
330+
@jinja_filter('json_encode_list') # Remove this for Neon
331331
def encode_list(data, encoding=None, errors='strict', keep=False,
332332
preserve_dict_class=False, preserve_tuples=False):
333333
'''

salt/utils/jinja.py

+20
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,26 @@ def to_bool(val):
278278
return False
279279

280280

281+
@jinja_filter('tojson')
282+
def tojson(val, indent=None):
283+
'''
284+
Implementation of tojson filter (only present in Jinja 2.9 and later). If
285+
Jinja 2.9 or later is installed, then the upstream version of this filter
286+
will be used.
287+
'''
288+
options = {'ensure_ascii': True}
289+
if indent is not None:
290+
options['indent'] = indent
291+
return (
292+
salt.utils.json.dumps(
293+
val, **options
294+
).replace('<', '\\u003c')
295+
.replace('>', '\\u003e')
296+
.replace('&', '\\u0026')
297+
.replace("'", '\\u0027')
298+
)
299+
300+
281301
@jinja_filter('quote')
282302
def quote(txt):
283303
'''

salt/utils/templates.py

+4
Original file line numberDiff line numberDiff line change
@@ -358,8 +358,12 @@ def opt_jinja_env_helper(opts, optname):
358358
jinja_env = jinja2.Environment(undefined=jinja2.StrictUndefined,
359359
**env_args)
360360

361+
tojson_filter = jinja_env.filters.get('tojson')
361362
jinja_env.tests.update(JinjaTest.salt_jinja_tests)
362363
jinja_env.filters.update(JinjaFilter.salt_jinja_filters)
364+
if tojson_filter is not None:
365+
# Use the existing tojson filter, if present (jinja2 >= 2.9)
366+
jinja_env.filters['tojson'] = tojson_filter
363367
jinja_env.globals.update(JinjaGlobal.salt_jinja_globals)
364368

365369
# globals

tests/unit/utils/test_jinja.py

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# -*- coding: utf-8 -*-
2+
'''
3+
Tests for salt.utils.jinja
4+
'''
5+
# Import Python libs
6+
from __future__ import absolute_import, unicode_literals, print_function
7+
8+
# Import Salt libs
9+
import salt.utils.jinja
10+
from tests.support.unit import TestCase
11+
12+
13+
class JinjaTestCase(TestCase):
14+
def test_tojson(self):
15+
'''
16+
Test the tojson filter for those using Jinja < 2.9. Non-ascii unicode
17+
content should be dumped with ensure_ascii=True.
18+
'''
19+
data = {'Non-ascii words': ['süß', 'спам', 'яйца']}
20+
result = salt.utils.jinja.tojson(data)
21+
expected = '{"Non-ascii words": ["s\\u00fc\\u00df", "\\u0441\\u043f\\u0430\\u043c", "\\u044f\\u0439\\u0446\\u0430"]}'
22+
assert result == expected, result

0 commit comments

Comments
 (0)