I am trying to get all undefined variables from a Jinja2 template. Assume that I have a template like below.
tmpstr = """
{% for row in csv %}
sample {{row.field1}} stuff {{row.field2}} morestuff {{row.field3}}
{% endfor %}
"""
and input dictionary as below
cxt = {'csv': [
{'field3': 1234, 'field4': 12314},
{'field3': 2222, 'field4': 1213}
]}
Here is how I try to render it.
env = Environment(undefined=Undefined)
tmp = env.from_string(tmpstr)
tmpsrc = tmp.render(cxt)
print(tmpsrc)
Template expect variables field1, field2 and field3 to be present. However field1 and field2 are not present. My aim is to find all missing variables.
Jinja2 silently ignores missing variables. Therefore I tried to add StrictUndefined option:
errs = []
try:
env = Environment(undefined=StrictUndefined)
tmp = env.from_string(tmpstr)
tmpsrc = tmp.render(cxt)
except Exception as e:
errs.append(str(e))
print(errs)
However this time jinja2 complains about only the first missing variable which is field1.
Therefore I tried another option which is DebugUndefined.
This option does not raise an exception and leaves missing variables placeholder in the template output untouched. Thus I can not collect missing variables.
Can you please suggest how can I get missing variables in a jinja2 template?
Here is runnable code if anyone wants to try it out:
from jinja2 import BaseLoader,Environment,StrictUndefined,DebugUndefined,Undefined
tmpstr = """
{% for row in csv %}
sample {{row.field1}} stuff {{row.field2}} morestuff {{row.field3}}
{% endfor %}
"""
cxt = {'csv': [
{'field3': 1234, 'field4': 12314},
{'field3': 2222, 'field4': 1213}
]}
env = Environment(undefined=Undefined)
tmp = env.from_string(tmpstr)
tmpsrc = tmp.render(cxt)
print('CASE 1: undefined=Undefined')
print(tmpsrc)
errs = []
try:
env = Environment(undefined=StrictUndefined)
tmp = env.from_string(tmpstr)
tmpsrc = tmp.render(cxt)
except Exception as e:
errs.append(str(e))
print('CASE 2: undefined=StrictUndefined')
print(errs)
errs = []
try:
env = Environment(undefined=DebugUndefined)
tmp = env.from_string(tmpstr)
tmpsrc = tmp.render(cxt)
except Exception as e:
errs.append(str(e))
print('CASE 3: undefined=DebugUndefined')
print(errs)
print(tmpsrc)