Search code examples
perltemplate-toolkit

Add custom function to Tpage (Template::Toolkit)


I am using Tpage (a command line wrapper for the Template Toolkit) and the documentation describes how to create custom virtual methods for scalar, list or hash variables, which would then be called as variable.custom_method(). However, I would like define some independent functions within the template that could be used directly. The idea is as follows:

This is my functions.tt file:

[%- PERL -%]

sub int2hex{
 my $intvar = shift;
 return sprintf("%X", $intvar);
};

[%- END -%]

[% myInteger=18 %]

This is my template.tt file:

Some text
The value of [%myInteger%] in hexadecimal is [% int2hex(myInteger) %]
More text

I would then call the template toolkit from the command line as follows:

tpage --eval_perl --pre_process=functions.tt template.tt > result.f

The expectation is that the function.tt file would be processed first and the int2hex() subroutine become available for the template.tt file. However, I get an error saying that undef error - int2hex is undefined. On the other hand, it does not complain about the myInteger.

Looks like the [% PERL %][% END %] portion of the file does not add the int2hex function to the list of methods. It is not straight-forward to implement this with the MACRO or Plugins as described here

Is there a simpler approach to define the functions in the template files directly?


Solution

  • You can make the subroutine available from the template by adding it to the $stash object that manages template variables. From http://www.template-toolkit.org/docs/modules/Template/Stash.html:

    Variables may reference hash arrays, lists, subroutines and objects as well as simple values. The stash automatically performs the right magic when dealing with variables, calling code or object methods, indexing into lists, hashes, etc.

    Code, adapted from https://www.perlmonks.org/?node_id=117720:

    [%- PERL -%]
    $stash->set('int2hex', sub {
     my $intvar = shift;
     return sprintf("%X", $intvar);
    });
    [%- END -%]
    
    [% myInteger=18 %]
    

    Result:

    Some text
    The value of 18 in hexadecimal is 12
    More text