SlideShare a Scribd company logo
Introduction To
   Template::Toolkit
         Introduction
       Basics: Part One
     Exercises (Hands On)
       Basics: Part Two
     Exercises (Hands On)
References and Further Reading
Introduction
•Who am I?
•What level of Perl expertise is required?
•What is Template::Toolkit?
Part One

•Simple mail-merge type example
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.
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";
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 %]
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";
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 %]
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";
Boolean logic: IF ELSE
[% IF age < 10 %]
[% ELSIF age < 18 %]
[% ELSE %]
[% END %]

The following conditional and boolean operators may be used:
  == != < <= > >= && || ! and or not
Boolean logic: SWITCH
[% SWITCH myvar %]
[% CASE 'value1' %]
[% CASE ['value2', 'value3'] %] # multiple values
[% CASE myhash.keys %]          # ditto
[% CASE %]                      # default
[% END %]
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 %]
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 %]
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";
Exercises
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
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>
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>
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";
Dodgy data
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' },
        { something => 'turnips > pears > grapes', something_else => '2 & 3 kg' },
        { something => '<script type="text/javascript">alert("Hi");</script>', something_else => '2
& 3 kg' },
      ]
   }
) || die $tt->error() . "n";
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 %] -->
That’s better
<tr><td>apples</td><td>1 KG</td></tr> <tr><td>pears</td><td>2 KG</td></tr>

<tr><td>turnips &gt; pears &gt; grapes</td><td>2 &amp; 3 KG</td></tr>

<tr><td>&lt;script
type=&quot;text/javascript&quot;&gt;alert(&quot;Hi&quot;);&lt;/script&gt;</td><td>2 &amp; 3
KG</td></tr>
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 %] -->
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
Use a vmethod to do a simple sort
         on a select list.
my $tt = Template->new(
   {
     INCLUDE_PATH => '/home/duncan/tt/htdocs/tt2',
     INTERPOLATE => 1,
     WRAPPER => 'wrapper.tt2'
   }
) || die "$Template::ERRORn";

$tt->process(
   's5.tt2',
   {
      rows => [
         { something => 'apples', something_else => '1 kg' },
         { something => 'pears', something_else => '2 kg' },
         { something => 'turnips > pears > grapes', something_else => '2 & 3 kg' },
         { something => '<>peas', something_else => '2 & 3 kg' },
         { something => 'apricots', something_else => '2 & 3 kg' },
      ],
      suppliers => [ 'Fred', 'Alan', 'Joe', 'Bert' ]
   }
) || die $tt->error() . "n";
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 %] -->
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
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>&pound;[% money(r.cost)
%]</td></tr>
[% END %]
</table>
<!-- End [% component.name %] -->
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

More Related Content

PPTX
CakePHP workshop
PDF
A Tour to MySQL Commands
PDF
35 Years of Open Source Software
PDF
PHP tips and tricks
PDF
DBIx::Class introduction - 2010
PDF
Command Bus To Awesome Town
KEY
Rspec and Rails
PDF
Your code sucks, let's fix it
CakePHP workshop
A Tour to MySQL Commands
35 Years of Open Source Software
PHP tips and tricks
DBIx::Class introduction - 2010
Command Bus To Awesome Town
Rspec and Rails
Your code sucks, let's fix it

What's hot (20)

PDF
Things I Believe Now That I'm Old
PDF
DBIx::Class beginners
KEY
Symfony2 Building on Alpha / Beta technology
TXT
Gta v savegame
PDF
Models and Service Layers, Hemoglobin and Hobgoblins
PDF
What's New in Perl? v5.10 - v5.16
PDF
Twig Brief, Tips&Tricks
PPT
DBIx-DataModel v2.0 in detail
PPT
Introduction to php
PDF
PHP 5.3 and Lithium: the most rad php framework
PDF
Simple Ways To Be A Better Programmer (OSCON 2007)
PDF
R57shell
PDF
Speed Things Up with Transients
KEY
Introduction to Perl Best Practices
PDF
Analysis of Fatal Utah Avalanches with Python. From Scraping, Analysis, to In...
DOC
Ex[1].3 php db connectivity
KEY
Refactor like a boss
ODP
How to Become a Tree Hugger: Random Forests and Predictive Modeling for Devel...
Things I Believe Now That I'm Old
DBIx::Class beginners
Symfony2 Building on Alpha / Beta technology
Gta v savegame
Models and Service Layers, Hemoglobin and Hobgoblins
What's New in Perl? v5.10 - v5.16
Twig Brief, Tips&Tricks
DBIx-DataModel v2.0 in detail
Introduction to php
PHP 5.3 and Lithium: the most rad php framework
Simple Ways To Be A Better Programmer (OSCON 2007)
R57shell
Speed Things Up with Transients
Introduction to Perl Best Practices
Analysis of Fatal Utah Avalanches with Python. From Scraping, Analysis, to In...
Ex[1].3 php db connectivity
Refactor like a boss
How to Become a Tree Hugger: Random Forests and Predictive Modeling for Devel...
Ad

Similar to Introduction to Template::Toolkit (20)

PDF
Code from LPW 2012 Template::Toolkit Workshop
ODP
Perl Teach-In (part 1)
PDF
tutorial7
PDF
tutorial7
PDF
Scripting3
PPT
Basic perl programming
PPTX
Bioinformatica p4-io
PDF
Marc’s (bio)perl course
ODP
Introducing Modern Perl
ODP
Programming in perl style
PDF
perl-pocket
PDF
perl-pocket
PDF
perl-pocket
PDF
perl-pocket
PDF
I, For One, Welcome Our New Perl6 Overlords
PDF
Crafting Custom Interfaces with Sub::Exporter
PDF
Learning Perl 6
PPT
CGI With Object Oriented Perl
PDF
PHP Tips & Tricks
KEY
Spl Not A Bridge Too Far phpNW09
Code from LPW 2012 Template::Toolkit Workshop
Perl Teach-In (part 1)
tutorial7
tutorial7
Scripting3
Basic perl programming
Bioinformatica p4-io
Marc’s (bio)perl course
Introducing Modern Perl
Programming in perl style
perl-pocket
perl-pocket
perl-pocket
perl-pocket
I, For One, Welcome Our New Perl6 Overlords
Crafting Custom Interfaces with Sub::Exporter
Learning Perl 6
CGI With Object Oriented Perl
PHP Tips & Tricks
Spl Not A Bridge Too Far phpNW09
Ad

Introduction to Template::Toolkit

  • 1. Introduction To Template::Toolkit Introduction Basics: Part One Exercises (Hands On) Basics: Part Two Exercises (Hands On) References and Further Reading
  • 2. Introduction •Who am I? •What level of Perl expertise is required? •What is Template::Toolkit?
  • 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";
  • 20. Dodgy data 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' }, { something => 'turnips > pears > grapes', something_else => '2 & 3 kg' }, { something => '<script type="text/javascript">alert("Hi");</script>', something_else => '2 & 3 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 &gt; pears &gt; grapes</td><td>2 &amp; 3 KG</td></tr> <tr><td>&lt;script type=&quot;text/javascript&quot;&gt;alert(&quot;Hi&quot;);&lt;/script&gt;</td><td>2 &amp; 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
  • 25. Use a vmethod to do a simple sort on a select list. my $tt = Template->new( { INCLUDE_PATH => '/home/duncan/tt/htdocs/tt2', INTERPOLATE => 1, WRAPPER => 'wrapper.tt2' } ) || die "$Template::ERRORn"; $tt->process( 's5.tt2', { rows => [ { something => 'apples', something_else => '1 kg' }, { something => 'pears', something_else => '2 kg' }, { something => 'turnips > pears > grapes', something_else => '2 & 3 kg' }, { something => '<>peas', something_else => '2 & 3 kg' }, { something => 'apricots', something_else => '2 & 3 kg' }, ], suppliers => [ 'Fred', 'Alan', 'Joe', 'Bert' ] } ) || die $tt->error() . "n";
  • 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>&pound;[% 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