Home > Software design >  Use of dots inside brackets to reach variable depth JSON in Jinja2 like ['object.subobject'
Use of dots inside brackets to reach variable depth JSON in Jinja2 like ['object.subobject'

Time:03-14

It's easy to get a specific variable object from a JSON array in Jinja like:

array['somekey']

but what if i want to access a value deeper in the nested list like:

array['somekey.subkey']

These dots inside the square brackets don't work so i can't access a value at a variable position?

Imagine a simple array of objects like the one below. In the template i want to set a variable that defines the path of the object i want to reach so that if the path is somekey1 i get somevalue1 but if the path is somekey3.subkey2 i get subvalue2 like:

python code

path = 'somekey3.subkey2'

jinja template code

{{ array[path] }}

expected result:

subvalue2

actual result:

no result (nothing gets printed on the screen)

full json array:

[{
    "somekey1": "somevalue1"
}, {
    "somekey2": "somevalue2"
}, {
    "somekey3": {
        "subkey1": "subvalue1",
        "subkey2": "subvalue2"
    }
}]

Thanks in advance!

CodePudding user response:

As my comment says, you'll likely need a custom filter to do dot access – luckily it's not hard to implement:

import jinja2


@jinja2.pass_environment
def dot(env: jinja2.Environment, obj, path):
    for key in path.split("."):
        obj = env.getattr(obj, key)  # use same semantics as jinja's own getattr
    return obj


env = jinja2.Environment()

env.filters["dot"] = dot

tpl = env.from_string("""
{{ obj | dot('somekey3.subkey2') }}
""".strip())

print(tpl.render(obj={
    "somekey3": {
        "subkey1": "subvalue1",
        "subkey2": "subvalue2"
    }
}))

The output is subvalue2 as expected.

You could expand this to do index accesses too with judicious use of isdigit.

  • Related