"if" tag doesn't behave like Jinja when testing absent environment variable
For example, I want to check if an environment variable is defined, then do something. Coming from Python + Jinja, I expect to have this code:
{% if get_env('TRACKING') %}
<!-- Inject tracking code -->
{% endif %}
But it doesn't work. I end up having to write:
{% if get_env(name='TRACKING', default='') != '' %}
<!-- Inject tracking code -->
{% endif %}
There are many limitations:
ifdoesn't consider empty string equivalent tofalse(error: "Functionget_envwas used in a logic operation but is not returning a bool"). I have to compare with another empty string.nameparameter must be explicitly written.- Have to explicitly write
default(error: "Environment variableTRACKINGnot found"). In Python,os.getenv(key)is equivalent toos.getenv(key, default=None), so you don't have to always writedefault.
- Will be fixed in v2 but no news on when that will happen
- Yes, args have to be named in Tera and that's not going to change
- In that case it was to match the Rust api. Not great looking back at it and should probably mirror more the Jinja version on v2
For 1. I think it's actually a good thing: in the same spirit as Rust, requiring explicit typing makes it simpler and removes doubts such as "is 'false' false" and potential footguns. I don't use templating all that often so maybe there are other aspects that I missed though.
@DuckDuckWhale That example is not relevant, because no programming language considers a string "false" equivalent to boolean false.
But from human perception, it is reasonable that empty string "" quivalent to false.
Right, that's not a very good example. Better examples would be 0 and NaN as in JS they are both falsy values. Also if implicit conversion is introduced and an empty string can be treated as false it creates confusion for all other types such as "is [] false?".
To clarify on my original point: requiring explicit comparison instead of implicitly casting from other types to bool can reduce both implementation and mental complexity while improving readability. It rules out the whole concept of falsiness and truthiness altogether. If you see an if you know exactly what the type the conditional; no need to check its type and see if the implicit conversion works as intended. To me this benefit in clarity vastly outweigh the cost of typing != ''. Like Rust, we can avoid this common pain point for JS by only taking bool.
@DuckDuckWhale The example of "is [] false" and JS behavior on truthy/falsy is also not relevant here, because as I stated right from the beginning, Tera is inspired from Jinja, so we just follow the logic from Python & Jinja.
I cannot imagine that someone is writing Jinja/Python code but using the behavior of JS.
Moreover, if you take JS as standard, even if get_env() != '' also not trustable, must be !==.
It is very much relevant here as Python also has the concept of truthy/falsy. I just picked JS as an example instead. 0 and [] are also falsy values in Python.
Mimicking Jinja2 is a good point though. However, Tera is a Rust template engine and doesn't aim to be 100% compatible. For folks coming form Rust this may be a friction point. Although I prefer being explicit, I don't know the design principles of this project so this is ultimately @Keats's call.
I don't object that "Python also has the concept of truthy/falsy". But between JS-style of truthy/falsy (where some empty data is not equivalent to false, like []) and Python style (where [] and 0 are equivalent to false), we just pick the Python because Tera is copying Jinja syntax, which is based on Python style.
It will be brain hack if you are writing Jinja code but have to "think" JS way. It is quite natural to write Jinja code and think the Python way.
I also agree that Tera won't be 100% compatible, so I still agree that name parameter must be explicit. But your argument about falsy/truthy and use JS as base is just ridiculous in the context of Jinja.
Tera is definitely using the truthiness checks from Python/Jinja2, not from any other languages.
As stated above my point is that from a language design point of view the existence of truthiness/falsiness itself is ambiguous and may be error-prone, and I used JS only as an example language that has this concept. This is the decision taken by the Rust community and it's far from "ridiculous". However I understand if that's a not a goal and Tera tries to be conservative in divergence from Jinja2.