`
`
Hi everyone!
I’m using this jinja2 macro for xml configs:
`
{%- macro print_opts(options, indent=’ ', count=0) %}
{% for key in options.keys() | sort2 %}
{% set value = options[key] %}
{% if value is string %}
{{- indentcount }}{{ key }} {{ ‘"’ + value.split(‘\t’) | join(‘" "’) + ‘"’ }}
{% elif value in [true, false] %}
{{- indentcount }}{{ key }} {{ value | lower }}
{% elif value is number %}
{{- indentcount }}{{ key }} {{ value }}
{% elif value is mapping %}
{{- indentcount }}<{{ key }}>
{{ print_opts(value, indent, count+1) -}}
{{- indentcount }}</{{ key.split()[0] }}>
{% elif value is sequence %}
{% for i in value | sort2 -%}
{{ print_opts({key: i}, indent, count) -}}
{%- endfor %}
{% else %}
{{- indentcount }}{{ key }} “{{ value }}”
{% endif %}
{% endfor %}
{% endmacro %}
`
This macro works fine with Python 2, but I need Python 3 support also. The problem is sort filter.
First, I’ve had the problem with dict sorting in Py3 (unorderable types: dict() < dict()) and created this custom sort filter:
`
from jinja2._compat import string_types
from operator import itemgetter
def environmentfilter(f):
“”“Decorator for marking environment dependent filters. The current
:class:Environment
is passed to the filter as first argument.
“””
f.environmentfilter = True
return f
@environmentfilter
def do_sort(environment, value, reverse=False, case_sensitive=False,
attribute=None):
if not case_sensitive:
def sort_func(item):
if isinstance(item, string_types):
item = item.lower()
return item
else:
sort_func = None
if attribute is not None:
getter = make_attrgetter(environment, attribute)
def sort_func(item, processor=sort_func or (lambda x: x)):
return processor(getter(item))
print(type(value))
if isinstance(value, list) and isinstance(value[0], dict):
return sorted(value, key=lambda x:sorted(x.keys()), reverse=reverse)
else:
return sorted(value, key=sort_func, reverse=reverse)
class FilterModule(object):
‘’’
custom jinja2 sort filter
‘’’
def filters(self):
return {
‘sort2’: do_sort
}
`
Here I am using different sorted key for list of dicts. But then I catch the next problem - list sorting.
With Python 2 print(type(value)) returns <type ‘list’> and sorting works as expected
With Python 3 it returns <class ‘dict_keys’> and I am getting different sorting per each ansible role running, config file always has changed state.
Please help me resolve this problem. Maybe someone knows a simpler solution to make this macro work on both Python versions.
Thanks