views:

145

answers:

3

Template-Toolkit seems to want to always interpolate undef to the empty string. So a template like this:

Result is [% some_object.some_method (1, undef, 2) %]

or this:

Result is [% ttvar %]
          [% some_object.some_method (1, ttvar, 2) %]

produces a call to Perl like:

some_object->some_method (1, '', 2)

when what I want is:

some_object->some_method (1, undef, 2)

Is there any way to pass undef instead of an empty string?

+3  A: 

How about using [% PERL %]?

[% PERL %]
[% my_perl_code %]
[% END %]
Kinopiko
Ah yes, that should work - thanks! BUT - do you know how to reference the template variable in the EVAL_PERL code? E.g. how to use 'some_object', this doesn't work, "global symbol "$some_object" requires explicit package name":[% PERL %] $some_object->some_method (1, undef, 2);[% END %]
F5
This answer should provide information on how to turn this feature on.
Brad Gilbert
Good point; you need to use EVAL_PERL when creating the Template object: my $tt = Template->new ({EVAL_PERL => 1});http://template-toolkit.org/docs/modules/Template.html#method_newhttp://template-toolkit.org/docs/modules/Template.html#section_EVAL_PERL
F5
@F5: re using template var with EVAL_PERL: U should be able to do this: [% PERL %]$stash->get( 'some_object' )->some_method(1, undef, 2);[% END %]
draegtun
+2  A: 

This is a design decision with Template Toolkit. From page 50 of the Perl Template Toolkit "Badger book":

The Template Toolkit won't complain if it encounters a variable for which it doesn't have a value defined. Instead, it will quietly use an empty string (i.e., nothing at all) for the value of the variable and continue to process the reminder of the template.

However what you can do is make TT provide a warning when it sees an undef by using the DEBUG option. See the SO question Can Perl’s Template Toolkit warn on undefined values? for more info.

/I3az/

draegtun
OK - so it seems there's no way to turn that off; the [% PERL %] solution appears to be the way to go.
F5
+4  A: 

I've added another answer to show an example of how EVAL_PERL works in TT:

use Template;
use DateTime;

my $tt = Template->new( EVAL_PERL => 1 );

my $vars = { foo => 'DateTime', bar => DateTime->now, p => 'print' };

my $file = q{
    [% SET hello = 'Hello world' %]
    [% PERL %]
    print "[% hello %]\n";
    print [% foo %]->now, "\n";
    [% p %] $stash->get( 'bar' )->ymd;
    [% END %]
};

$tt->process( \$file, $vars );

The above outputs the following:

Hello world
2009-11-03T15:31:50
2009-11-03

Because TT is acting as a pre-processor and produces the following Perl code to interpret:

print "hello world\n";
print DateTime->now, "\n";
print $stash->get( 'bar' )->ymd;

NB. $stash in above line is provided by TT and is a reference to the top level stash object.

/I3az/

draegtun
Excellent, thanks; didn't know about the TT $stash
F5
Despite using TT for donkey years I hadn't come across it before either! But then I've managed to avoid using EVAL_PERL and so never needed to know ;-) Here's where I found it: http://template-toolkit.org/docs/manual/Directives.html#section_PERL
draegtun