This is a question about Template Toolkit for perl.
I render my templates with a little command-line utility that has the following option enabled
DEBUG => Template::Constants::DEBUG_UNDEF,
The syntax is render <file.tt> var1 val1 var2 val2 ....
This is very convenient because the user gets prompts about values that need to be defined, for example
$ render file.tt
undef error - var1 is undefined
$ render file.tt var1 foo
undef error - var2 is undefined
$ render file.tt var1 foo var2 bar
... template renders correctly
For some (optional) values, templates provide defaults, for example:
[%- DEFAULT
hostname = 0
%]
Then the template body would typically contain:
[% IF hostname %] hostname = [% hostname %][% ELSE %][% -- a comment, variable hostname not provided %][% END %]
How do I make the above idiom work for variables where 0 is a valid value?
I want the following to happen:
render template.tt
Template renders:
-- this is a comment, variable enable_networking not provided
For
render template.tt enable_networking 0
I want
enable_networking = 0
The problem is differentiating between defined values and false values. I have tried using -1 (instead of 0) both in the DEFAULT block and in the [% IF enable_networking == -1 %] statement.
However, the following DEFAULT block
[% DEFAULT enable_networking = -1 %]
will override value 0 specified on the command-line. (It sees a enable_networking is false and sets it to -1)
Are there any easy work-arounds (some config variable maybe?)
To check if a variable is undefined or not you could check if its
sizemethod returns something greater than 0. Of course this case only aplies if the variable is not initialized or defined at all (enable_networking = ''has size = 1, the same withenable_networking = 0)To check if a variable is not false... well... first you have to describe wich type of value is false.
In this case i will take size = 0 (or size doesn't exists) as undefined, -1 as false and everything else as true:
With the code above if you run
The output will be
enable_networking = 0And if you run
The output will be
-- a comment, variable enable_networking not providedeven if you don't declare[% DEFAULT enable_networking = -1 %]EDIT 1:
The
lengthmethod is better suited for this job:Using
lengthinstead ofsizealso allows you to useenable_networking = ''as FALSE along with -1EDIT 2:
Ok, after the comments i found a workaround that do the trick: the
TRY-CATCHdirectives...For optional variables that can have value of 0 the objective would be to
TRYsetting the variable value to itself, if the variable is defined the value will be assigned, otherwise weCATCHthe undef error and set the default value. For any other type of variable we can use theDEFAULTdirective:With this new template if you run