NAME
Text::Template::Base - Expand template text with embedded Perl
SYNOPSIS
use Text::Template::Base;
DESCRIPTION
This module is an enhanced version of M-J. Dominus' Text::Template version 1.45.
I have tried to contact M-J. to get my patches (included in this distribution in the patches/
directory) into Text::Template but never got an answer.
For usage information see Text::Template.
DIFFERENCES COMPARED TO Text::Template 1.45
The OUT
function (to be used within templates)
The OUT
function serves a similar purpose as $OUT
. It is automatically installed in the package the template is evaluated in. Hence a template can look like this:
Here is a list of the things I have got for you since 1907:
{ foreach $i (@items) {
OUT " * $i\n";
}
}
The advantage of the function over $OUT
is that it wastes less memory. Suppose you have a very long list of items. Using $OUT
it is first accumulated in that variable and then appended to the resulting string. That means it uses twice the memory (for a short time). With the OUT
function each piece of generated text is immediately appended to the resulting string.
But the main advantage lies in using the OUT
function in combination with the OUTPUT
option to fill_in
. Now a piece of output is directly put out and nothing at all accumulated.
There is also a drawback. $OUT
is an ordinary variable and can be used as such. This template cannot be easily converted to using OUT
:
Here is a list of the things I have got for you since 1907:
{ foreach $i (@items) {
$OUT .= " * $i\n";
if( some_error ) {
# forget the output so far
$OUT = "An error has occurred";
last;
}
}
}
NOTE, the OUT
function doesn't work with the SAFE
option.
The OUTPUT
parameter to new()
and fill_in
Text::Template
allows for a file handle to be passed as OUTPUT
parameter. Each chunk of output will be written directly to this handle.
With this module a subroutine can be passed instead of the file handle. Each chunk of output will be passed to this function as the only parameter.
$template->fill_in(OUTPUT => sub { print $_[0] }, ...);
The FILENAME
parameter to new()
and fill_in
When Text::Template
generates error messages it tries to include the file name and line number where the error has happened. But for some template types the file name is not known. In such cases Text::Template
simply uses the string template
. With the FILENAME
parameter this string can be configured.
The EVALCACHE
parameter to new()
and fill_in
Normally Text::Template
calls eval
each time to evaluate a piece of Perl code. This can be a performance killer if the same piece is evaluated over and over again.
One solution could be to wrap the piece of code into a subroutine, have Perl compile that routine only once and use it many times.
If EVALCACHE
is given Text::Template
does exactly that. A piece of perl code is wrapped as a subroutine, compiled and the resulting code references are saved in the EVALCACHE
with the actual perl text as key.
EVALCACHE
does not currently work if the SAFE
option is used.
There are a few pitfalls with that method that have to be looked out by the template programmer. Suppose you have that piece of code in a template:
my $var = 5;
sub function {
return $var++;
}
$OUT.=function() for( 1..3 );
That piece will producess the string 567
in $OUT
each time it is evaluated. But if it is wrapped into a subroutine it looks like:
sub {
my $var = 5;
sub function {
return $var++;
}
$OUT.=function() for( 1..3 );
};
If that anonymous function is called several times it produces 012
, 345
and so on. The problem is that named functions (like function
) are created at compile time while anonymous functions (like the outer sub) at run time. Hence, the $var
my-variable is not available in function
. Perl solves thar conflict by creating a separate variable $var
at compile time that is initially undef
. Evaluated in numerical context is gives 0
.
So, how can the code fragment be converted so that the function is created at runtime. There are 2 ways. Firstly, you can use function references:
sub {
my $var = 5;
my $function = sub {
return $var++;
};
$OUT.=$function->() for( 1..3 );
};
Now both the inner and the outer functions are anomymous and both are created at runtime. But calling function
as $function->()
may not be convenient. So, the second way uses a local
ized symbol:
sub {
my $var = 5;
local *function = sub {
return $var++;
};
$OUT.=function() for( 1..3 );
};
For more information see http://perl.apache.org/docs/general/perl_reference/perl_reference.html#my____Scoped_Variable_in_Nested_Subroutines
The #line
directive in templates
Correct line numbers are crucial for debugging. If a template is fetched from a larger file and passed to Text::Template::Base
as string Text::Template::Base
doesn't know at which line of the larger file the template starts. Hence, it cannot produce correct error messages.
The solution is to prepend the template string (assuming default delimiters are used) with
{#line NUMBER}
where NUMBER
is the actual line number where the template starts.
If custom delimiters are used replace the braces by them. Assuming [%
and %]
as delimiters that directive should look:
[%#line NUMBER%]
Note that there must not be any other character between the opening delimiter and the #line
and between the NUMBER
and the closing delimiter not even spaces. Also, there must be only one space between #line
and NUMBER
.
The #line
directive works not only at the beginning of a template. Suppose you have a larger template and have cut out some parts prior to passing it to Text::Template::Base
as a string. Replace these parts with correct #line
directives and your error messages are correct.
AUTHOR
Torsten Foertsch, <torsten.foertsch@gmx.net>
Most of this module is borrowed from Text::Template by Mark-Jason Dominus, Plover Systems