slow initial import. (`#765`_)
- Python 2.6 and 3.3 are not supported anymore.
- The `map` filter in async mode now automatically awaits
+- Added `default` parameter for the `map` filter. (`#985`_)
.. _#765: https://github.com/pallets/jinja/issues/765
+.. _#985: https://github.com/pallets/jinja/pull/985
Version 2.10.1
return value.lower() if isinstance(value, string_types) else value
-def make_attrgetter(environment, attribute, postprocess=None):
+def make_attrgetter(environment, attribute, postprocess=None, default=None):
"""Returns a callable that looks up the given attribute from a
passed object with the rules of the environment. Dots are allowed
to access attributes of attributes. Integer parts in paths are
for part in attribute:
item = environment.getitem(item, part)
+ if default and isinstance(item, Undefined):
+ item = default
+ break
+
if postprocess is not None:
item = postprocess(item)
Users on this page: {{ users|map(attribute='username')|join(', ') }}
+ If the list of objects may not contain the given attribute, a default
+ value may be provided.
+
+ .. sourcecode:: jinja
+
+ {{ users|map(attribute='username', default='Anonymous')|join(', ') }}
+
Alternatively you can let it invoke a filter by passing the name of the
filter and the arguments afterwards. A good example would be applying a
text conversion filter on a sequence:
if len(args) == 2 and 'attribute' in kwargs:
attribute = kwargs.pop('attribute')
+ default = kwargs.pop('default', None)
if kwargs:
raise FilterArgumentError('Unexpected keyword argument %r' %
next(iter(kwargs)))
- func = make_attrgetter(context.environment, attribute)
+ func = make_attrgetter(context.environment, attribute, default=default)
else:
try:
name = args[2]
tmpl = env.from_string('{{ users|map(attribute="name")|join("|") }}')
assert tmpl.render(users=users) == 'john|jane|mike'
+ def test_attribute_map_default(self, env):
+ class User(object):
+ def __init__(self, name):
+ self.name = name
+ class NotUser(object):
+ def __init__(self, not_name):
+ self.not_name = not_name
+ env = Environment()
+ users = [
+ User('john'),
+ User('jane'),
+ NotUser('plant'),
+ ]
+ tmpl = env.from_string('{{ users|map(attribute="name", default="anonymous")|join("|") }}')
+ assert tmpl.render(users=users) == 'john|jane|anonymous'
+
def test_empty_map(self, env):
env = Environment()
tmpl = env.from_string('{{ none|map("upper")|list }}')