Templating Tools - Text::Template (
Page 4 of 4 )
Mark-Jason Dominus' Text::Template has established itself as the de facto standard templating system for plain text. Its templating language is very simple indeed--anything between {and} is evaluated by Perl; everything else is left alone.
It is an object-oriented module--you create a template object from a file, filehandle, or string, and then you fill it in:
use Text::Template;
my $template = Text::Template->new(TYPE => "FILE",
SOURCE => "email.tmpl");
my $output = $template->fill_in();
So, let's say we've got the following template:
Dear {$who},
Thank you for the {$modulename} Perl module, which has saved me
{$hours} hours of work this year. This would have left me free to play
{ int($hours*2.4) } games of go, which I would have greatly appreciated
had I not spent the time goofing off on IRC instead.
Love,
Simon
We set up our template object and our variables, and then we process the template:
use Text::Template;
my $template = Text::Template->new(TYPE => "FILE",
SOURCE => "email.tmpl");
$who = "Mark";
$modulename = "Text::Template";
$hours = 15;
print $template->fill_in();
And the output would look like:
Dear Mark,
Thank you for the Text::Template Perl module, which has saved me
15 hours of work this year. This would have left me free to play
36 games of go, which I would have greatly appreciated
had I not spent the time goofing off on IRC instead.
Love,
Simon
Notice that the fill-in variables--$who, $modulename, and so on--are not my variables. When you think about it, this ought to be obvious--the my variables are not in Text::Template's scope, and therefore it wouldn't be able to see them. This is a bit unpleasant: Text::Template has access to your package variables, and you have to do a bit more work if you want to avoid giving use strict a fit.
Text::Template has two solutions to this. The first is pretty simple--just move the fill-in variables into a completely different package:
use Text::Template;
my $template = Text::Template->new(TYPE => "FILE",
SOURCE => "email.tmpl");
$Temp::who = "Mark";
$Temp::modulename = "Text::Template";
$Temp::hours = 15;
print $template->fill_in(PACKAGE => "Temp");
That's slightly better, but it still doesn't please people for whom global variables are pure evil. If that's you, you can get around the problem by passing in a portable symbol table--that is, a hash:
use Text::Template;
my $template = Text::Template->new(TYPE => "FILE",
SOURCE => "email.tmpl");
print $template->fill_in(HASH => {
who => "Mark",
modulename => "Text::Template",
hours => 15
});
Please check back next week for the continuation of this article.