Reputation: 7136
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
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
Reputation: 1465
According to docs you can just do:
{{ p|d('', true) }}
Cause None
casts to False
in a boolean context.
Upvotes: 111
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
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
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'
Upvotes: 7
Reputation: 43
You can simply add "default none" to your variable as the form below mentioned:
{{ your_var | default('NONE', boolean=true) }}
Upvotes: -2
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
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
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
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
Reputation: 2145
As addition to other answers, one can write something else if variable is None like this:
{{ variable or '' }}
Upvotes: 61