Jinja: Allow map filter to retrieve multiple items

Created on 29 Feb 2016  ·  4Comments  ·  Source: pallets/jinja

At the moment, the map function can only be used like this:

[{'path':'/var/file1', 'mtime': '123', 'mode': '600',...},{'path':'/var/file2', 'mtime': '123', 'mode': 644, ...}]|map(attribute='path')

with the return of

['/var/file1', '/var/file2']

(Docs: http://jinja.pocoo.org/docs/dev/templates/#map)

I want to propose allowing this:

[{'path':'/var/file1', 'mtime': '123', 'mode': '600',...},{'path':'/var/file2', 'mtime': '123', 'mode': 644, ...}]|map(attribute=['path', 'mtime'])

or

[{'path':'/var/file1', 'mtime': '123', 'mode': '600',...},{'path':'/var/file2', 'mtime': '123', 'mode': 644, ...}]|map(attributes=['path', 'mtime'])

which should return

[{'path':'/var/file1', 'mtime': '123'},{'path':'/var/file2', 'mtime': '123'}]

You can already see what this is useful for: manipulating a list of dicts so that these dicts only retain a limited set of attributes.

Most helpful comment

If anyone still needs this you can use the following code (put in playbooks/filter_plugins/mapattributes.py):

#!/usr/bin/env python
class FilterModule(object):
  def filters(self):
    return { 'mapattributes': self.mapattributes }

  def mapattributes(self, list_of_dicts, list_of_keys):
    l = []
    for di in list_of_dicts:
      newdi = { }
      for key in list_of_keys:
        newdi[key] = di[key]
      l.append(newdi)
    return l

Use via:

ansible_mounts | mapattributes(['mount', 'size_total', 'size_available',])

All 4 comments

Would LOVE this feature.

I'm not clear why this is needed in templates. Just iterating over the dictionaries and using the attributes you need will accomplish the same thing. If you need different data, it's probably a better idea to do that manipulation in Python before rendering. I could _maybe_ see a use for it returning tuples.

If anyone still needs this you can use the following code (put in playbooks/filter_plugins/mapattributes.py):

#!/usr/bin/env python
class FilterModule(object):
  def filters(self):
    return { 'mapattributes': self.mapattributes }

  def mapattributes(self, list_of_dicts, list_of_keys):
    l = []
    for di in list_of_dicts:
      newdi = { }
      for key in list_of_keys:
        newdi[key] = di[key]
      l.append(newdi)
    return l

Use via:

ansible_mounts | mapattributes(['mount', 'size_total', 'size_available',])

Why is this issue closed and Nee6ione solution not implemented officially ? It would be so much simpler if this was supported without any additional plugins

Was this page helpful?
0 / 5 - 0 ratings