home | O'Reilly's CD bookshelfs | FreeBSD | Linux | Cisco | Cisco Exam  


Perl CookbookPerl CookbookSearch this book

21.17. Templating with Template Toolkit

21.17.2. Solution

Use the Template Toolkit and Apache::Template.

21.17.3. Discussion

The Template Toolkit (TT2) is a general templating system that can be used not just for web pages, but for any kind of templated text. The Apache::Template module is an Apache content handler that uses TT2 to build the returned page. The biggest benefit of TT2 is that it has a simple language for variables, loops, and data structures, which can be used instead of Perl for presentation logic. This simple language can be read and written by people who don't know Perl.

This recipe documents Version 2 of the Template Toolkit. As with HTML::Mason, there's far more to TT2 that we can possibly cover here. This recipe is just a tour of some of the highlights of TT2's syntax and functionality. The Template Toolkit is well documented at http://www.template-toolkit.org, and in the upcoming book Perl Template Toolkit, by Darren Chamberlain, Dave Cross, and Andy Wardley (O'Reilly).

21.17.3.3. Perl code

If you want to execute Perl, use a PERL directive:

[% PERL %]
  my @numbers = (1 .. 3);
  print join(" ... ", @numbers);
[% END %]

Anything printed from within a PERL block becomes part of the final document. PERL blocks execute under use strict, so it pays to use lexical variables.

These lexical variables are separate from the TT2 variables like i, the loop iterator in the earlier example. To make a Perl value accessible to TT2 code, or vice versa, you must use the stash. This is the TT2 symbol table, and is accessible through the $stash variable automatically present in PERL blocks:

[% PERL %]
  my @numbers = (1 .. 3);
  my $text = join(" ... ", @numbers);
  $stash->set(counting => $text);
[% END %]
Here's how you count to three: [% counting %].  Wasn't that easy?

Normally you use Perl code for business logic (e.g., fetching values from databases) and TT2 code for presentation logic (e.g., building tables). The Perl code sets TT2 variables with the results of the business logic (e.g., the values from the database) so that the presentation logic has values to put into the template. In practice, most people prefer to disable TT2EvalPerl and keep Perl code out of their templates. this strict separation of business from presentation logic means a customized version of Apache::Template is needed to load the Perl code and place data in the stash.

You can initialize TT2 variables from TT2 as well:

[% text = "1 ... 2 ... 3" %]                    <!-- string -->
[% names = [ "Larry", "Tom", "Tim" ] %]         <!-- array  -->
[% language = { Larry => "Perl 6",              <!-- hash   -->
                Tom   => "Perl 5",
                Tim   => "Latin" } %]
[% people = { Larry => { Language => "Perl 6",  <!-- nested structure -->
                         Town     => "Mountain View" },
              Tom   => { Language => "Perl 5",
                         Town     => "Boulder" } } %]

Similarly, you can fetch TT2 values from the stash:

[% FOREACH i = [1 .. 3] %]
  [% PERL %]
    my $number = $stash->get("i");
    $stash->set(doubled => 2*$number);
  [% END %]
  [% doubled %] ...
[% END %]
2 ... 4 ... 6 ...

From within a PERL block, you can also use modules. It's more efficient, however, to load the modules when Apache starts up by replacing the PERL block's use Some::Thing with a PerlModule Some::Thing in httpd.conf.

21.17.3.4. Data structures

The stash lets you put scalars, arrays, hashes, even subroutines into the world of TT2 code. Here's an array definition and access:

[% names = [ "Nat", "Jenine", "William", "Raley" ] %]
The first person is [% names.0 %].
The first person is Nat.

The period (.) separates the structure name from the field you want to access. This works for hashes as well:

[% age = { Nat => 30, Jenine => 36, William => 3, Raley => 1.5 } %]
Nat is [% age.Nat %] (and he feels it!)
Nat is 30 (and feels it!)

Unlike Perl, TT2 code doesn't put [ ] or { } around the array position or hash key whose value you're accessing. This is part of the simplicity of TT2 code, and why non-programmers can easily modify it. It also hides the implementation—age.1 could just as easily be implemented through an array, a hash, or an object, without requiring changes in the template.

If your index is stored in another variable, use a $:

[% age = { Nat => 30, Jenine => 36, William => 3, Raley => 1.5 } %]
[% name = "Nat" %]
Nat is [% age.$name %] (and he feels it)
Nat is 30 (and feels it!)

Loop over an array or hash with FOREACH:

[% FOREACH name = names %]
  Hi, [% name %]!
[% END %]
Hi, Nat! Hi, Jenine! Hi, William! Hi, Raley!

[% FOREACH person = age %]
  [% person.key %] = [% person.value %].
[% END %]
Nat is 30. Jenine is 36. William is 3. Raley is 1.5.

The key and person methods can be called on a hash loop iterator to get the current key and value, respectively. TT2 also makes a loop variable available in loops, from which you can access the current position, find out whether the current position is the first or last, and more. Table 21-1 lists the loop variable methods and their meanings.

Table 21-1. loop variable methods

Method

Meaning

size

Number of elements in the list

max

Index number of last element (size - 1)

index

Index of current iteration from 0 to max

count

Iteration counter from 1 to size (i.e., index + 1)

first

True if the current iteration is the first

last

True if the current iteration is the last

prev

Return the previous item in the list

next

Return the next item in the list

To build a table with alternating row colors, do the following:

[% folks = [ [ "Larry",  "Mountain View" ],
             [ "Tom",    "Boulder"       ],
             [ "Jarkko", "Helsinki"      ],
             [ "Nat",    "Fort Collins"  ] ] %]
<table>
[% FOREACH row = folks %]
  <tr [% IF loop.index % 2 %]
          bgcolor="#ffff00"
      [% ELSE %]
          bgcolor="#ffff80"
      [% END %] >
  [% FOREACH col = row %]
    <td>[% col %]</td>
  [% END %]
  </tr>
[% END %]
</table>


Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.