mcd
mcd

Reputation: 7136

Jinja2 template variable if None Object set a default value

How to make a variable in Jijna2 default to "" if object is None instead of doing something like this?

{% if p %}   
    {{ p.User['first_name']}}
{% else %}
    NONE
{%endif %}

So if object p isNone. I want to default the values of p (first_name and last_name) to "". Basically:

nvl(p.User[first_name'], "")

Error receiving:

Error: jinja2.exceptions.UndefinedError
UndefinedError: 'None' has no attribute 'User'

Upvotes: 266

Views: 428507

Answers (13)

tbicr
tbicr

Reputation: 26070

Use the none test (not to be confused with Python's None object!):

{% if p is not none %}   
    {{ p.User['first_name'] }}
{% else %}
    NONE
{% endif %}

or:

{{ p.User['first_name'] if p is not none else 'NONE' }}

or if you need an empty string:

{{ p.User['first_name'] if p is not none }}

Upvotes: 438

Torindo
Torindo

Reputation: 1955

{{p.User['first_name'] or 'My default string'}}

Upvotes: 181

mitenka
mitenka

Reputation: 1465

According to docs you can just do:

{{ p|d('', true) }}

Cause None casts to False in a boolean context.

Upvotes: 111

Genarito
Genarito

Reputation: 3433

I solved this by defining a custom filter (in my case I needed in the cases None, False or empty strings):

def __default_if_empty(value, default) :
    """Returns a default value if the given value evaluates to False."""
    return value if value else default

env = Environment(
    # Your config...
)
env.filters["default_if_empty"] = __default_if_empty

Then use that filter in the template:

{{ your_var | default_if_empty('') }}

Upvotes: 0

tarun kumar
tarun kumar

Reputation: 170

if you want to set your own default value instead of None than simply do this

{{your_var|default:'default name'}}

Upvotes: 2

kirosc
kirosc

Reputation: 174

With ChainableUndefined, you can do that.

>>> import jinja2
>>> env = jinja2.Environment(undefined=jinja2.ChainableUndefined)
>>> env.from_string("{{ foo.bar['baz'] | default('val') }}").render()
'val'

source

Upvotes: 7

yelmir
yelmir

Reputation: 43

You can simply add "default none" to your variable as the form below mentioned:

{{ your_var | default('NONE', boolean=true) }}

Upvotes: -2

Apollo
Apollo

Reputation: 15

As of Ansible 2.8, you can just use:

{{ p.User['first_name'] }}

See https://docs.ansible.com/ansible/latest/porting_guides/porting_guide_2.8.html#jinja-undefined-values

Upvotes: -2

Apollo
Apollo

Reputation: 15

As another solution (kind of similar to some previous ones):

{{ ( p is defined and p.User is defined and p.User['first_name'] ) |default("NONE", True) }}

Note the last variable (p.User['first_name']) does not have the if defined test after it.

Upvotes: 1

Tamas Hegedus
Tamas Hegedus

Reputation: 29916

I usually define an nvl function, and put it in globals and filters.

def nvl(*args):
    for item in args:
        if item is not None:
            return item
    return None

app.jinja_env.globals['nvl'] = nvl
app.jinja_env.filters['nvl'] = nvl

Usage in a template:

<span>Welcome {{ nvl(person.nick, person.name, 'Anonymous') }}<span>

// or 

<span>Welcome {{ person.nick | nvl(person.name, 'Anonymous') }}<span>

Upvotes: 0

Guoqiang
Guoqiang

Reputation: 357

To avoid throw a exception while "p" or "p.User" is None, you can use:

{{ (p and p.User and p.User['first_name']) or "default_value" }}

Upvotes: 10

Ivan Bryzzhin
Ivan Bryzzhin

Reputation: 2145

As addition to other answers, one can write something else if variable is None like this:

{{ variable or '' }}

Upvotes: 61

pawel7318
pawel7318

Reputation: 3583

Following this doc you can do this that way:

{{ p.User['first_name']|default('NONE') }}

Upvotes: 27

Related Questions