1. Introduction To
Template::Toolkit
Introduction
Basics: Part One
Exercises (Hands On)
Basics: Part Two
Exercises (Hands On)
References and Further Reading
4. Template for a letter
Dear [% name %],
It has come to our attention that your account is in
arrears to the sum of [% debt %].
Please settle your account before [% deadline %] or we
will be forced to revoke your Licence to Thrill.
The Management.
5. Perl script to call it
use strict;
use Template;
my $tt = Template->new({
INCLUDE_PATH => '/usr/local/templates',
INTERPOLATE => 1,
}) || die "$Template::ERRORn";
my $vars = {
name => 'Count Edward van Halen',
debt => '3 riffs and a solo',
deadline => 'the next chorus',
};
$tt->process('letters/overdrawn', $vars)
|| die $tt->error(), "n";
6. Multiple letters
[% FOREACH d IN debtors %]
Dear [% d.name %],
It has come to our attention that your account is in
arrears to the sum of [% d.debt %].
Please settle your account before [% d.deadline %] or we
will be forced to revoke your Licence to Thrill.
The Management.
[% END %]
7. Perl fragment
my $vars = { debtors => [
{
name => 'Count Edward van Halen',
debt => '3 riffs and a solo',
deadline => 'the next chorus',
},
{
name => ‘Baron Eric Clapton',
debt => ‘1 badge',
deadline => ‘tomorrow',
}
]
};
$tt->process('letters/overdrawn', $vars)
|| die $tt->error(), "n";
8. Multiple letters with logic
[% FOREACH d = debtors %]
Dear [% d.name %],
It has come to our attention that your account is in
arrears to the sum of [% d.debt %].
Please settle your account before [% d.deadline %] or we
will be forced to revoke your Licence to Thrill.
[% IF d.final %]This is your last chance.[% END %]
The Management.
[% END %]
9. Perl fragment
my $debtors = [
{
name => 'Count Edward van Halen',
debt => '3 riffs and a solo',
deadline => 'the next chorus',
},
{
name => ‘Baron Eric Clapton',
debt => ‘1 badge',
deadline => ‘tomorrow',
final => 1
}
];
$tt->process('letters/overdrawn', $debtors)
|| die $tt->error(), "n";
10. Boolean logic: IF ELSE
[% IF age < 10 %]
[% ELSIF age < 18 %]
[% ELSE %]
[% END %]
The following conditional and boolean operators may be used:
== != < <= > >= && || ! and or not
11. Boolean logic: SWITCH
[% SWITCH myvar %]
[% CASE 'value1' %]
[% CASE ['value2', 'value3'] %] # multiple values
[% CASE myhash.keys %] # ditto
[% CASE %] # default
[% END %]
12. Alternative contents
[% FOREACH d IN debtors %]
Dear [% d.name %],
Thank you for your recent payment of [% d.debt %].
Your account is now clear and you may continue to thrill.
The Management.
[% END %]
13. Include other templates
[% FOREACH d IN debtors %]
Dear [% d.name %],
[% IF d.angry -%]
[% INCLUDE angry_letter.tt2 %]
[% ELSE -%]
[% INCLUDE grateful_letter.tt2 %]
[% END -%]
The Management.
[% END %]
14. Perl fragment
my $debtors = [
{
name => 'Count Edward van Halen',
debt => '3 riffs and a solo',
deadline => 'the next chorus',
},
{
name => ‘Baron Eric Clapton',
debt => ‘1 badge',
deadline => ‘tomorrow',
final => 1,
angry => 1,
}
];
$tt->process('letters/overdrawn', $debtors)
|| die $tt->error(), "n";
16. Part Two
•Adding a wrapper for the header and footer
•Adding simple filters to encoding entities or control case
•Using a vmethod to add row numbers
•Sorting a select list
•Formatting currency
17. Adding a wrapper
Content-Type: text/html; charset=ISO-8859-1
<html>
<head>
</head>
<body>
<h1>Introduction to TT</h2>
[%# Header and footer will be the same on all pages %]
<table>
<tr><th>Something</th><th>Something Else</th></tr>
[% FOREACH r IN rows %]
<tr><td>[% r.something %]</td><td>[% r.something_else %]</td></tr>
[% END %]
</table>
</body>
</html>
18. Move the common content to wrapper.tt
Content-Type: text/html; charset=ISO-8859-1
<html>
<head>
</head>
<body>
<h1>Introduction to TT</h2>
[% content %]
</body>
</html>
19. Tell TT about the wrapper
#! /usr/bin/perl
use strict; use warnings; use CGI; use Template;
# Using a wrapper.
my $tt = Template->new(
{
INCLUDE_PATH => '/home/duncan/tt/htdocs/tt2',
INTERPOLATE => 1,
WRAPPER => 'wrapper.tt2'
}
) || die "$Template::ERRORn";
$tt->process(
's2.tt2',
{
rows => [
{ something => 'apples', something_else => '1 kg' },
{ something => 'pears', something_else => '2 kg' }
]
}
) || die $tt->error() . "n";
21. Encode it!
<! [% component.name %] -->
[%# Using a filter to encode entities and control case. %]
<table>
<tr><th>Something</th><th>Something Else</th></tr>
[% FOREACH r IN rows %]
<tr><td>[% r.something FILTER html_entity %]</td><td>[% r.something_else FILTER html_entity
FILTER upper %]</td></tr>
[% END %]
</table>
<!-- End [% component.name %] -->
22. That’s better
<tr><td>apples</td><td>1 KG</td></tr> <tr><td>pears</td><td>2 KG</td></tr>
<tr><td>turnips > pears > grapes</td><td>2 & 3 KG</td></tr>
<tr><td><script
type="text/javascript">alert("Hi");</script></td><td>2 & 3
KG</td></tr>
23. Use a vmethod to add row
numbers
<! [% component.name %] -->
[%# Using a vmethod to add row number %]
<table>
<tr><th>No</th><th>Something</th><th>Something Else</th></tr>
[% FOREACH r IN rows %]
<tr><td>([% loop.index %])</td>
<td>[% r.something FILTER html_entity %]</td><td>[% r.something_else FILTER html_entity
FILTER upper %]</td></tr>
[% END %]
</table>
<!-- End [% component.name %] -->
24. With row numbers
No Something Something Else
(0) apples 1 KG
(1) pears 2 KG
(2) turnips > pears > grapes 2 & 3 KG
(3) <>peas 2 & 3 KG
(4) apricots 2 & 3 KG
26. Adding the sort vmethod
[%# Using a vmethod to do a simple sort on a select list %]
<! [% component.name %] -->
<select>
[% FOREACH s IN suppliers.sort %]
<option value="s"/>[% s %]
[% END %]
</select>
<table>
<tr><th>No</th><th>Something</th><th>Something Else</th></tr>
[% FOREACH r IN rows %]
<tr><td> ([% loop.index %])</td><td>[% r.something FILTER html_entity %]</td><td>[%
r.something_else FILTER html_entity FILTER upper %]</td></tr>
[% END %]
</table>
<!-- End [% component.name %] -->
27. Using the Format plugin on
currency
No Something Something Else Cost
(0) apples 1 KG £5.67
(1) pears 2 KG £3.33333333333333
(2) turnips > pears > grapes 2 & 3 KG £4.123
(3) <>peas 2 & 3 KG £2
(4) apricots 2 & 3 KG £3
28. The script with the plugin
[% USE money=format('%.2f') -%]
<select>
[% FOREACH s IN suppliers.sort %]
<option value="s"/>[% s %]
[% END %]
</select>
<table>
<tr><th>No</th><th>Something</th><th>Something Else</th><th>Cost</ht></tr>
[% FOREACH r IN rows %]
<tr><td> ([% loop.index %])</td><td>[% r.something FILTER html_entity %]</td><td>[%
r.something_else FILTER html_entity FILTER upper %]</td><td>£[% money(r.cost)
%]</td></tr>
[% END %]
</table>
<!-- End [% component.name %] -->
29. Further Reading
Template Toolkit [Paperback]
•Darren Chamberlain,
•Dave Cross,
•Andy Wardley
Also documented on MetaCPAN: https://metacpan.org/
It has its own website: http://www.template-toolkit.org/
226 plugins listed on MetaCPAN