Why doesn't my condition logic work as expected in Jinja2/CherryPy?
Asked Answered
C

6

37
{% if bCat2 == True %}
    <div>True</div>
{% else %}
    <div>False</div>

Returns <div>False</div> even when bCat2 is True. Thanks, Andrew

Catricecatrina answered 8/12, 2011 at 15:34 Comment(0)
A
44

Option 1: Most common solution

Solve that like python do.

Check if variable is true

{% if bCat2 %}
    <div>True</div>
{% else %}
    <div>False</div>

Check if variable is false

{% if not bCat2 %}
    <div>False</div>
{% else %}
    <div>True</div>

Jinja2 If documentation

Option 2: Jinja2 sameas solution

Solve like jinja2 do. Becareful with boolean lowercase.

Check if variable is true

{% if bCat2 is sameas true %}
    <div>True</div>
{% endif %}

Check if variable is false

{% if bCat2 is sameas false %}
    <div>False</div>
{% endif %}

Jinja2 sameas documentation

Amatruda answered 16/4, 2018 at 14:59 Comment(2)
For those stumbling over this: When your put the boolean variable in --extra-vars(of ansible-playbook), don't do it this way: --extra-vars="bCat2=True". This won't work, because the command line app makes a bCat2 var with type string. Better is to use json here: --extra-vars='{ "bCat2": true }'.Ralf
Or you could give the var an empty val and that will be interpreted as false. Like so: --extra-vars='bCat2='Mellar
A
67

This part of documentation can help you:

The special constants true, false and none are indeed lowercase. Because that caused confusion in the past, when writing True expands to an undefined variable that is considered false, all three of them can be written in title case too (True, False, and None). However for consistency (all Jinja identifiers are lowercase) you should use the lowercase versions.

Source: http://jinja.pocoo.org/docs/templates/

Try that code:

{% if bCat2 == true %}
<div>True</div>
{% else %}
<div>False</div>
{% endif %}
Abhenry answered 20/12, 2011 at 9:6 Comment(3)
This should be the correct answer. Iterating over a large list and changing each bool to string as per the accepted answer may become costly if the list is large and we want to send the large list to the template.Rework
Weirdly this does not work for me... is there an update?Yee
Can't update since I am too far from Python at present.Abhenry
A
44

Option 1: Most common solution

Solve that like python do.

Check if variable is true

{% if bCat2 %}
    <div>True</div>
{% else %}
    <div>False</div>

Check if variable is false

{% if not bCat2 %}
    <div>False</div>
{% else %}
    <div>True</div>

Jinja2 If documentation

Option 2: Jinja2 sameas solution

Solve like jinja2 do. Becareful with boolean lowercase.

Check if variable is true

{% if bCat2 is sameas true %}
    <div>True</div>
{% endif %}

Check if variable is false

{% if bCat2 is sameas false %}
    <div>False</div>
{% endif %}

Jinja2 sameas documentation

Amatruda answered 16/4, 2018 at 14:59 Comment(2)
For those stumbling over this: When your put the boolean variable in --extra-vars(of ansible-playbook), don't do it this way: --extra-vars="bCat2=True". This won't work, because the command line app makes a bCat2 var with type string. Better is to use json here: --extra-vars='{ "bCat2": true }'.Ralf
Or you could give the var an empty val and that will be interpreted as false. Like so: --extra-vars='bCat2='Mellar
G
15

The proper way to do this in Jinja2 is:

{% if bCat2 is sameas true %}
    <div>True</div>
{% elif bCat2 is sameas false %}
    <div>False</div>
{% endif %}

The reason why you cannot do

{% if bCat2 == true %}

is that if bCat2 == 1 or bCat2 == 1.0 it will also be considered True.

Glenine answered 17/3, 2018 at 0:53 Comment(0)
C
11

To test a Boolean variable in a template, convert it to a string in Python

str(bCat2)

and then compared it to a string in the template

{% if bCat2 == 'True' %}
    <div>True</div>
{% else %}
    <div>False</div>
Catricecatrina answered 9/12, 2011 at 13:0 Comment(1)
But it's better to compare directly in Jinja2, without converting the boolean to a string, not @Andrew? I think the @Amatruda answer would be the easier and better way to test if a boolean is true or false. Just for curiosity, why should someone lean towards the solution you propose?Canoodle
S
5

I would like to add that if your logic is a bit more complex you might want to read about scopes.

As mentioned in official documentation:

As of version 2.10 more complex use cases can be handled using namespace objects which allow propagating of changes across scopes:

{% set ns = namespace(found=false) %}
{% for item in items %}
    {% if item.check_something() %}
        {% set ns.found = true %}
    {% endif %}
    * {{ item.title }}
{% endfor %}
Found item having something: {{ ns.found }}
Signpost answered 28/9, 2018 at 15:6 Comment(0)
B
1

take this:

{% if bCat2 is true %}
    <div>True</div>
{% else %}
    <div>False</div>
{% endif %}

my test:

$ python -m pip install j2cli
$ j2 <(echo "{% if false is true %}
    <div>True</div>
{% else %}
    <div>False</div>
{% endif %}")

    <div>False</div>

$ j2 <(echo "{% if true is true %}
    <div>True</div>
{% else %}
    <div>False</div>
{% endif %}")

    <div>True</div>
Bili answered 15/3, 2021 at 19:52 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.