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?

innaM
  • 47,505
  • 4
  • 67
  • 87
F5.
  • 63
  • 6
  • Do you need to distinguish between the cases of empty string and undef, or is it OK to just convert empty strings into `undef`? –  Nov 03 '09 at 14:26
  • Yes, that's the whole point - I need to keep undef undef, not have TT change it to the empty string. I.e. the perl method needs to be able to check for whether the parameter is defined or not. – F5. Nov 03 '09 at 14:33

3 Answers3

3

How about using [% PERL %]?

[% PERL %]
[% my_perl_code %]
[% END %]
  • 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. Nov 03 '09 at 14:47
  • This answer should provide information on how to turn this feature on. – Brad Gilbert Nov 03 '09 at 15:13
  • 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_new http://template-toolkit.org/docs/modules/Template.html#section_EVAL_PERL – F5. Nov 03 '09 at 15:18
  • @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 Nov 03 '09 at 15:26
3

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/

Community
  • 1
  • 1
draegtun
  • 22,441
  • 5
  • 48
  • 71
  • OK - so it seems there's no way to turn that off; the [% PERL %] solution appears to be the way to go. – F5. Nov 03 '09 at 14:50
3

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
  • 22,441
  • 5
  • 48
  • 71
  • 1
    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 Nov 03 '09 at 22:33
  • While this is a way to solve the stated issue, its *much better* to avoid having PERL blocks in your templates, and find a way to solve the issue in the Perl calling TT instead. – castaway May 13 '11 at 13:56
  • @castaway: Totally agree. But I don't think this answer deserves a downvote :( – draegtun Sep 15 '11 at 12:23