lambda as argument to jinja2 filter?

I have a workaround, I'm sorting a dict object:

registers = dict(
    CMD = dict(
        address = 0x00020,
        name = 'command register'),
    SR = dict(
        address = 0x00010,
        name = 'status register'),
)

I wanted to loop over the register dict, but sort by address. So I needed a way to sort by the 'address' field. To do this, I created a custom filter and pass the lambda expression as a string, then I use Python's builtin eval() to create the real lambda:

def my_dictsort(value, by='key', reverse = False):

    if by == 'key':
        sort_by = lambda x: x[0].lower() # assumes key is a str

    elif by == 'value':
        sort_by = lambda x: x[1]

    else:
        sort_by = eval(by)   # assumes lambda string, you should error check

    return sorted(value, key = sort_by, reverse = reverse)

With this function, you can inject it into the jinja2 environment like so:

env = jinja2.Environment(...)
env.filters['my_dictsort'] = my_dictsort
env.globals['lookup'] = lookup            # queries a database, returns dict

And then call it from your template:

{% for key, value in lookup('registers') | my_dict_sort("lambda x:x[1]['address']") %}
{{"""\
    static const unsigned int ADDR_{key} = 0x0{address:04X}; // {name}
""" | format(key = key, address = value['address'], name = value['name']) 
}}
{% endfor %}

Output:

static const unsigned int ADDR_SR = 0x00010; // status register
static const unsigned int ADDR_CMD = 0x00020; // command register

So you can pass a lambda as a string, but you'll have to add a custom filter to do it.


No, you cannot pass general Python expression to filter in Jinja2 template

The confusion comes from jinja2 templates being similar to Python syntax in many aspects, but you shall take it as code with completely independent syntax.

Jinja2 has strict rules, what can be expected at which part of the template and it generally does not allow python code as is, it expect exact types of expressions, which are quite limited.

This is in line with the concept, that presentation and model shall be separated, so template shall not allow too much logic. Anyway, comparing to many other templating options, Jinja2 is quite permissible and allows quite a lot of logic in templates.