SlideShare ist ein Scribd-Unternehmen logo
1 von 29
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

Weitere ähnliche Inhalte

Was ist angesagt?

Things I Believe Now That I'm Old
Things I Believe Now That I'm OldThings I Believe Now That I'm Old
Things I Believe Now That I'm OldRoss Tuck
 
DBIx::Class beginners
DBIx::Class beginnersDBIx::Class beginners
DBIx::Class beginnersleo lapworth
 
Symfony2 Building on Alpha / Beta technology
Symfony2 Building on Alpha / Beta technologySymfony2 Building on Alpha / Beta technology
Symfony2 Building on Alpha / Beta technologyDaniel Knell
 
Gta v savegame
Gta v savegameGta v savegame
Gta v savegamehozayfa999
 
Models and Service Layers, Hemoglobin and Hobgoblins
Models and Service Layers, Hemoglobin and HobgoblinsModels and Service Layers, Hemoglobin and Hobgoblins
Models and Service Layers, Hemoglobin and HobgoblinsRoss Tuck
 
What's New in Perl? v5.10 - v5.16
What's New in Perl?  v5.10 - v5.16What's New in Perl?  v5.10 - v5.16
What's New in Perl? v5.10 - v5.16Ricardo Signes
 
Twig Brief, Tips&Tricks
Twig Brief, Tips&TricksTwig Brief, Tips&Tricks
Twig Brief, Tips&TricksAndrei Burian
 
DBIx-DataModel v2.0 in detail
DBIx-DataModel v2.0 in detail DBIx-DataModel v2.0 in detail
DBIx-DataModel v2.0 in detail Laurent Dami
 
PHP 5.3 and Lithium: the most rad php framework
PHP 5.3 and Lithium: the most rad php frameworkPHP 5.3 and Lithium: the most rad php framework
PHP 5.3 and Lithium: the most rad php frameworkG Woo
 
Simple Ways To Be A Better Programmer (OSCON 2007)
Simple Ways To Be A Better Programmer (OSCON 2007)Simple Ways To Be A Better Programmer (OSCON 2007)
Simple Ways To Be A Better Programmer (OSCON 2007)Michael Schwern
 
R57shell
R57shellR57shell
R57shellady36
 
Speed Things Up with Transients
Speed Things Up with TransientsSpeed Things Up with Transients
Speed Things Up with TransientsCliff Seal
 
Introduction to Perl Best Practices
Introduction to Perl Best PracticesIntroduction to Perl Best Practices
Introduction to Perl Best PracticesJosé Castro
 
Analysis of Fatal Utah Avalanches with Python. From Scraping, Analysis, to In...
Analysis of Fatal Utah Avalanches with Python. From Scraping, Analysis, to In...Analysis of Fatal Utah Avalanches with Python. From Scraping, Analysis, to In...
Analysis of Fatal Utah Avalanches with Python. From Scraping, Analysis, to In...Matt Harrison
 
Ex[1].3 php db connectivity
Ex[1].3 php db connectivityEx[1].3 php db connectivity
Ex[1].3 php db connectivityMouli Chandira
 
Refactor like a boss
Refactor like a bossRefactor like a boss
Refactor like a bossgsterndale
 
How to Become a Tree Hugger: Random Forests and Predictive Modeling for Devel...
How to Become a Tree Hugger: Random Forests and Predictive Modeling for Devel...How to Become a Tree Hugger: Random Forests and Predictive Modeling for Devel...
How to Become a Tree Hugger: Random Forests and Predictive Modeling for Devel...Matt Harrison
 

Was ist angesagt? (20)

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

Ähnlich wie Introduction to Template::Toolkit

Code from LPW 2012 Template::Toolkit Workshop
Code from LPW 2012 Template::Toolkit WorkshopCode from LPW 2012 Template::Toolkit Workshop
Code from LPW 2012 Template::Toolkit Workshopduncanmg
 
Shell Script Disk Usage Report and E-Mail Current Threshold Status
Shell Script  Disk Usage Report and E-Mail Current Threshold StatusShell Script  Disk Usage Report and E-Mail Current Threshold Status
Shell Script Disk Usage Report and E-Mail Current Threshold StatusVCP Muthukrishna
 
Your Custom WordPress Admin Pages Suck
Your Custom WordPress Admin Pages SuckYour Custom WordPress Admin Pages Suck
Your Custom WordPress Admin Pages SuckAnthony Montalbano
 
Engines: Team Development on Rails (2005)
Engines: Team Development on Rails (2005)Engines: Team Development on Rails (2005)
Engines: Team Development on Rails (2005)lazyatom
 
Template Toolkit
Template ToolkitTemplate Toolkit
Template Toolkitdwm042
 
Idoc script beginner guide
Idoc script beginner guide Idoc script beginner guide
Idoc script beginner guide Vinay Kumar
 
Rails Antipatterns | Open Session with Chad Pytel
Rails Antipatterns | Open Session with Chad Pytel Rails Antipatterns | Open Session with Chad Pytel
Rails Antipatterns | Open Session with Chad Pytel Engine Yard
 
Bag Of Tricks From Iusethis
Bag Of Tricks From IusethisBag Of Tricks From Iusethis
Bag Of Tricks From IusethisMarcus Ramberg
 
Ruby Language - A quick tour
Ruby Language - A quick tourRuby Language - A quick tour
Ruby Language - A quick touraztack
 
sri_ITSD325_IP3Code-ShoppingAbout UsfrmAboutus.aspx@ Page.docx
sri_ITSD325_IP3Code-ShoppingAbout UsfrmAboutus.aspx@ Page.docxsri_ITSD325_IP3Code-ShoppingAbout UsfrmAboutus.aspx@ Page.docx
sri_ITSD325_IP3Code-ShoppingAbout UsfrmAboutus.aspx@ Page.docxwhitneyleman54422
 
Rooted 2010 ppp
Rooted 2010 pppRooted 2010 ppp
Rooted 2010 pppnoc_313
 
Let's write secure drupal code!
Let's write secure drupal code!Let's write secure drupal code!
Let's write secure drupal code!Balázs Tatár
 
The Browser Environment - A Systems Programmer's Perspective [sinatra edition]
The Browser Environment - A Systems Programmer's Perspective [sinatra edition]The Browser Environment - A Systems Programmer's Perspective [sinatra edition]
The Browser Environment - A Systems Programmer's Perspective [sinatra edition]Eleanor McHugh
 
Practical PHP by example Jan Leth-Kjaer
Practical PHP by example   Jan Leth-KjaerPractical PHP by example   Jan Leth-Kjaer
Practical PHP by example Jan Leth-KjaerCOMMON Europe
 
RubyBarCamp “Полезные gems и plugins”
RubyBarCamp “Полезные gems и plugins”RubyBarCamp “Полезные gems и plugins”
RubyBarCamp “Полезные gems и plugins”apostlion
 

Ähnlich wie Introduction to Template::Toolkit (20)

Code from LPW 2012 Template::Toolkit Workshop
Code from LPW 2012 Template::Toolkit WorkshopCode from LPW 2012 Template::Toolkit Workshop
Code from LPW 2012 Template::Toolkit Workshop
 
Tt subtemplates-caching
Tt subtemplates-cachingTt subtemplates-caching
Tt subtemplates-caching
 
Shell Script Disk Usage Report and E-Mail Current Threshold Status
Shell Script  Disk Usage Report and E-Mail Current Threshold StatusShell Script  Disk Usage Report and E-Mail Current Threshold Status
Shell Script Disk Usage Report and E-Mail Current Threshold Status
 
Your Custom WordPress Admin Pages Suck
Your Custom WordPress Admin Pages SuckYour Custom WordPress Admin Pages Suck
Your Custom WordPress Admin Pages Suck
 
Mojolicious
MojoliciousMojolicious
Mojolicious
 
Engines: Team Development on Rails (2005)
Engines: Team Development on Rails (2005)Engines: Team Development on Rails (2005)
Engines: Team Development on Rails (2005)
 
Template Toolkit
Template ToolkitTemplate Toolkit
Template Toolkit
 
Idoc script beginner guide
Idoc script beginner guide Idoc script beginner guide
Idoc script beginner guide
 
Apache Velocity 1.6
Apache Velocity 1.6Apache Velocity 1.6
Apache Velocity 1.6
 
Rails Antipatterns | Open Session with Chad Pytel
Rails Antipatterns | Open Session with Chad Pytel Rails Antipatterns | Open Session with Chad Pytel
Rails Antipatterns | Open Session with Chad Pytel
 
Coding part
Coding partCoding part
Coding part
 
Bag Of Tricks From Iusethis
Bag Of Tricks From IusethisBag Of Tricks From Iusethis
Bag Of Tricks From Iusethis
 
Ruby Language - A quick tour
Ruby Language - A quick tourRuby Language - A quick tour
Ruby Language - A quick tour
 
sri_ITSD325_IP3Code-ShoppingAbout UsfrmAboutus.aspx@ Page.docx
sri_ITSD325_IP3Code-ShoppingAbout UsfrmAboutus.aspx@ Page.docxsri_ITSD325_IP3Code-ShoppingAbout UsfrmAboutus.aspx@ Page.docx
sri_ITSD325_IP3Code-ShoppingAbout UsfrmAboutus.aspx@ Page.docx
 
Rooted 2010 ppp
Rooted 2010 pppRooted 2010 ppp
Rooted 2010 ppp
 
Let's write secure drupal code!
Let's write secure drupal code!Let's write secure drupal code!
Let's write secure drupal code!
 
PHP PPT FILE
PHP PPT FILEPHP PPT FILE
PHP PPT FILE
 
The Browser Environment - A Systems Programmer's Perspective [sinatra edition]
The Browser Environment - A Systems Programmer's Perspective [sinatra edition]The Browser Environment - A Systems Programmer's Perspective [sinatra edition]
The Browser Environment - A Systems Programmer's Perspective [sinatra edition]
 
Practical PHP by example Jan Leth-Kjaer
Practical PHP by example   Jan Leth-KjaerPractical PHP by example   Jan Leth-Kjaer
Practical PHP by example Jan Leth-Kjaer
 
RubyBarCamp “Полезные gems и plugins”
RubyBarCamp “Полезные gems и plugins”RubyBarCamp “Полезные gems и plugins”
RubyBarCamp “Полезные gems и plugins”
 

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