Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sane way to define default variable values from within a jinja template?

Tags:

python

jinja2

I'd like to set default values for variables used in my Jinja template inside of the template itself. Looking at the Jinja2 documentation, I don't see any way to do this. Have I missed something? I see the "default" filter, but I want to set the value template wide instead of a use-by-use basis.

I spent an hour or so trying to teach myself enough about the Jinja2 extension writing process to write an extension tag setdefault, which could look like this:

{% setdefault animal = 'wumpas' %}

The desired effect would be equivalent to the set tag if the assigned-to name was undefined, but to have no effect if the assigned-to name was defined. I have thusfar failed to get this to work.

My work around is to circumvent jinja entirely and make a compound file; the area before a special marker is a (yaml) mapping of default values, and the area after a marker is the jinja template. An proof of concept implementation of this that seems to work fine is:

skel_text = """\
animal: wumpas
%%
The car carried my {{animal}} to the vet.
"""
class Error(Exception): pass
_skel_rx = re.compile(
    r"""((?P<defaults>.*?)^%%[ \t]*\n)?(?P<template>.*)""",
    re.MULTILINE|re.DOTALL)
_env = jinja2.Environment(trim_blocks=True)
def render(skel, **context):
    m = _skel_rx.match(skel_text)
    if not m:
        raise Error('skel split failed')
    defaults = yaml.load(m.group('defaults') or '{}')
    template = _env.from_string(m.group('template') or '')
    template.globals.update(defaults)
    return template.render(**context)

print render(skel_text)
print render(skel_text, animal='cat')

So, is there a way to do the equivalent in stock Jinja2, or how might one write an extension to accomplish the desired effect?

like image 225
Matt Anderson Avatar asked Dec 18 '10 19:12

Matt Anderson


People also ask

How do you assign values in Jinja?

{{ }} tells the template to print the value, this won't work in expressions like you're trying to do. Instead, use the {% set %} template tag and then assign the value the same way you would in normal python code. It was great explanation and simple one.

How are variables in Jinja2 templates specified?

A Jinja template doesn't need to have a specific extension: . html , . xml , or any other extension is just fine. A template contains variables and/or expressions, which get replaced with values when a template is rendered; and tags, which control the logic of the template.


1 Answers

What worked for me was to use a filter:

t = '''Hello {{name | default('John Doe')}}'''
like image 162
Jared Avatar answered Oct 06 '22 14:10

Jared