So much for simple templates. Because Text::Template evaluates the code in braces as honest-to-goodness Perl code, we can do a whole lot more with templates. Let's suppose we're invoicing for some design work:
$client = "Acme Motorhomes and Eugenics Ltd."; %jobs = ("Designing the new logo" => 450.00, "Letterheads" => 300.00, "Web site redesign" => 900.00, "Miscellaneous Expenses" => 33.75 );
We can create a template to do the work for us--the invoicing work, that is, not the design work:
{my $total=0; ''} To {$client}:
Thank you for consulting the services of Fungly Foobar Design Associates. Here is our invoice in accordance with the work we have carried out for you:
{ while (my ($work, $price) = each %jobs) { $OUT .= $work . (" " x (50 - length $work)). sprintf("%6.2f", $price)."\n"; $total += $price; } }
Total {sprintf "%6.2f",$total}
Payment terms 30 days.
Many thanks, Fungly Foobar
What's going on here? First, we set up a private variable, $total, in the template and set it to zero. However, since we don't want a 0 appearing at the top of our template, we make sure our code snippet returns '' so it adds nothing to the output. This is a handy trick.
Next we want to loop over the jobs hash. Adding each price to the total is simple enough, but we also want to add a line to the template for each job. What we'd like to say is something like this:
{ while (my ($work, $price) = each %jobs) { }
{$work} {$price}
{ $total += $price; } }
However, Text::Template doesn't work like that: each snippet of code must be an independent, syntactically correct piece of Perl. So how do we write multiple lines to the template? This is where the magical $OUT variable comes in. If you use $OUT in your template, that's taken as the output from the code snippet. We can append to this variable each time we go through the loop, and it'll all be filled into the template at the end.