BUY THIS BOOK
Add to Cart

Print Book $39.95


Safari Books Online

What is this?

Add to UK Cart

Print Book £28.50

What is this?

Looking to Reprint this content?


Perl Template Toolkit
Perl Template Toolkit By Andy Wardley, Darren Chamberlain, Dave Cross
December 2003
Pages: 590

Cover | Table of Contents | Colophon


Table of Contents

Chapter 1: Getting Started with the Template Toolkit
The Template Toolkit is an all-Perl template processing system. Unlike many other Perl templating systems, it is as proficient at producing HTML as it is at producing XML, PDF, or any other output format. It has its own simple templating language, so templates can be written and edited by people who do not know Perl. And it supports command-line, modular, CGI, and mod_perl operation.
In this chapter, we compare the Template Toolkit to other templating systems such as HTML::Mason and HTML::Template, describe how to install it, then show you what templates look like and how to process them. The goal of this chapter is to get you started—you should be able to install the Template Toolkit, write and understand basic templates, and know how to process the templates from the command line, from Perl programs, and from mod_perl.
The basic task of a template processor is to output some amount of changeable data surrounded by some unchanging data. A simple example of this is a form letter, where the same text is sent to many different people, with just the name, address, and other personal details being changed. The template contains the fixed ("boilerplate") text together with special markup tags indicating where the variable pieces of data are to be placed.
Example 1-1 shows a template for such a form letter. This template is marked up using the default style of the Template Toolkit, where the [% ... %] tags indicate variable values. Everything else is fixed text that passes through the processor untouched.
Example 1-1. A form letter template, destruction.tt
People of [% planet %], your attention please. 

This is [% captain %] of the
Galactic Hyperspace Planning Council.  
   
As you will no doubt be aware, the plans 
for development of the outlying regions
of the Galaxy require the building of a 
hyperspatial express route through your 
star system, and regrettably your planet
is one of those scheduled for destruction.
   
The process will take slightly less than
[% time %].
   
Thank you.
A template processor takes the template, together with a list of the variable data to be included in the letter, and produces a finished letter. The Template Toolkit provides
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
What the Template Toolkit Does
The basic task of a template processor is to output some amount of changeable data surrounded by some unchanging data. A simple example of this is a form letter, where the same text is sent to many different people, with just the name, address, and other personal details being changed. The template contains the fixed ("boilerplate") text together with special markup tags indicating where the variable pieces of data are to be placed.
Example 1-1 shows a template for such a form letter. This template is marked up using the default style of the Template Toolkit, where the [% ... %] tags indicate variable values. Everything else is fixed text that passes through the processor untouched.
Example 1-1. A form letter template, destruction.tt
People of [% planet %], your attention please. 

This is [% captain %] of the
Galactic Hyperspace Planning Council.  
   
As you will no doubt be aware, the plans 
for development of the outlying regions
of the Galaxy require the building of a 
hyperspatial express route through your 
star system, and regrettably your planet
is one of those scheduled for destruction.
   
The process will take slightly less than
[% time %].
   
Thank you.
A template processor takes the template, together with a list of the variable data to be included in the letter, and produces a finished letter. The Template Toolkit provides tpage for doing just that from the command line. Pass the name of the template file to tpage as a command-line option, along with any number of --define options to provide values for variables. If the preceding template is stored in the destruction.tt file in the current directory, the following command processes it:
$ tpage --define planet=Earth \
>       --define captain="Prostetnic Vogon Jeltz" \
>       --define time="two of your earth minutes" \
>       destruction.tt
The output this generates is shown in Example 1-2.
Example 1-2. Form letter generated by template in Example 1-1
People of Earth, your attention please.
   
This is Prostetnic Vogon Jeltz of the 
Galactic Hyperspace Planning Council.  
   
As you will no doubt be aware, the plans 
for development of the outlying regions
of the Galaxy require the building of a 
hyperspatial express route through your 
star system, and regrettably your planet
is one of those scheduled for destruction.
   
The process will take slightly less than
two of your earth minutes.
   
Thank you.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
The Templating Ecosystem
At least half a dozen mature and respected templating systems are available for Perl. The best-known and best-supported template processors include the following:
Text::Template
Text::Template is a library for generating form letters, building HTML pages, or filling in templates generally. A template is a piece of text that has little Perl programs embedded in it here and there. When you fill in a template, you evaluate the little programs and replace them with their values. These programs are written in Perl: you embed Perl code in your template, with { at the beginning and } at the end. If you want a variable interpolated, you write it the way you would in Perl. If you need to make a loop, you can use any of the Perl loop constructions. All the Perl built-in functions are available.
Text::Template is available from http://www.plover.com/~mjd/perl/Template/ or from CPAN (http://search.cpan.org/dist/Text-Template/).
HTML::Template
HTML::Template attempts to make using HTML templates easy and natural. It extends standard HTML with a few HTML-like tags, and enforces the divide between design and programming by restricting what a template is capable of doing. By limiting the programmer to using just simple variables and loops in the HTML, the template remains accessible to designers and other non-Perl people. The use of HTML-like syntax goes further to make the format understandable to others.
HTML::Template is available from CPAN (http://search.cpan.org/dist/HTML-Template/).
HTML::Mason
HTML::Mason is a Perl-based web site development and delivery system. Mason allows web pages and sites to be constructed from shared, reusable building blocks called components. Components contain a mix of Perl and HTML, and can call each other and pass values back and forth like subroutines. Components increase modularity and eliminate repetitive work: common design elements (headers, footers, menus, logos) can be extracted into their own components where they need be changed only once to affect the whole site. Mason also includes powerful filtering and templating facilities and an HTML/data caching model.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Installing the Template Toolkit
At any one time you can download from the Web at least two possible versions of the Template Toolkit: a stable version and a developer version. The stable version has a version number such as 2.10, and has been widely tested before release. The developer versions have version numbers such as 2.10a, and typically have bug fixes and early implementations of new features. Generally, you should install the latest stable release.
The Template Toolkit is available from the Comprehensive Perl Archive Network (CPAN). You can always download the most recent stable version of the Template Toolkit from http://search.cpan.org/dist/Template-Toolkit/ (which is where most people download it).
In addition, a web site is dedicated to the Template Toolkit. Located at http://www.template-toolkit.org, this site offers the latest stable version, as well as a number of other goodies such as native packages of the Template Toolkit for Debian GNU/Linux, Mac OS X (for installation using Fink), and Microsoft Windows (for installation using ActiveState's Perl Package Manager).
You can also get developer versions of the Template Toolkit from the web site. Normally, you need to download only the current stable version, but if you come across a bug that isn't fixed in the CPAN version, you may need to use a developer release.
If a developer release isn't cutting-edge enough for you, the web site contains information on how to get access to the CVS repository, which is where the very latest versions of the Template Toolkit source code are kept. If you want to add functionality to the Template Toolkit or have found a bug that you can fix, and you want your patch to be accepted by Template Toolkit developers, you should make your changes against the current CVS HEAD.
Installing the Template Toolkit is like installing any other Perl module (see perlmodinstall(1) for platform-specific details). The basic idea is as follows:
$ perl Makefile.PL
$ make
$ make test
$ make install
A few optional modules and pages of documentation come with the Template Toolkit, and how much of that gets installed is controlled by arguments to
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Documentation and Support
In this section, we take a look at the support that is available for the Template Toolkit.
The Template Toolkit comes with an incredible amount of documentation. The documentation is supplied in the standard Perl Plain Old Documentation (POD) format. Once you have installed the Template Toolkit, you can see any of the documentation pages using perldoc or man, just as you can with any other Perl module:
$ perldoc Template           # should always work
$ man Template               # does not work everywhere
During the Template Toolkit installation procedure you are offered the chance to install HTML versions of the documentation. The default location for the installation of these files is /usr/local/tt2 under Unix and C:/Program Files/Template Toolkit 2 under Win32. The installation procedure prompts for alternate locations.
If you are running a web server on your local machine, you can configure it to know where these files are. For example, you might put the contents of Example 1-4 in the httpd.conf for an Apache web server.
Example 1-4. Apache configuration directives to view Template Toolkit documentation
# TT2
Alias /tt2/images/   /usr/local/tt2/images/
Alias /tt2/docs/     /usr/local/tt2/docs/html/
Alias /tt2/examples/ /usr/local/tt2/examples/html/
   
<Directory /usr/local/tt2/>
    Options Indexes
    AllowOverride None
    Order allow,deny
    Allow from all
</Directory>
You can now access the locally installed documentation by pointing your browser at http://localhost/tt2/docs. For more information on configuring your web server, see the INSTALL file that comes with the Template Toolkit.
The complete documentation set is also available online at the Template Toolkit web site. You can find it at http://www.template-toolkit.org/docs.html.
A large number of manual pages come with the Template Toolkit. Here is a list of some of the most useful ones:
Template
The manual page for the Template module, the main module for using the Template Toolkit from Perl.
Template::Manual
An introduction and table of contents for the rest of the manual pages.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Using the Template Toolkit
The rest of this chapter provides a brief introduction to using the Template Toolkit. We look at the structure and syntax of templates, showing how variables and directives are embedded in plain text and expanded by the template processing engine. We talk about some of the different kinds of directives that the Template Toolkit provides, what they're used for, and how you go about using them.
We start by looking at the four main ways of using the Template Toolkit to process templates: from the command line using the tpage and ttree programs; from a Perl script using the Template module; and in a mod_perl-enabled Apache web server using the Apache::Template module.
The tpage program provides a quick and easy way to process a template file from the command line. The name of the template file is specified as a command-line argument. This is processed through the Template Toolkit processing engine, and the resultant output is printed to STDOUT:
$ tpage infile
You can use the > file redirect operator (if your operating system supports it, or something similar) to save the output into another file:
$ tpage infile > outfile
In this example, the input template, infile, is processed by tpage with the output saved in outfile. If something goes wrong and the template can't be processed (for example, if the input file specified doesn't exist or contains an invalid template directive or markup error), an error is printed to STDERR, and tpage exits without generating any standard output.
The following shows what happens if we try and coerce tpage into processing a file, nosuchfile, which doesn't exist on our system:
$ tpage nosuchfile
file error - nosuchfile: not found at /usr/bin/tpage line 60.
tpage offers just one command-line option, --define, which allows you to provide values for template variables embedded in the document. We saw this earlier in Example 1-1 where it processed the Vogon form letter:
$ tpage --define planet=Earth \
>       --define captain="Prostetnic Vogon Jeltz" \
>       --define time="two of your earth minutes" \
>       destruction.tt
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
The Template Toolkit Language
The Template Toolkit language is a presentation language rather than a general-purpose programming language. It provides the kind of features that you would expect to see in a regular programming language, including loops, conditional tests, and the ability to manipulate variable values. However, in this case they serve a slightly different purpose. The Template Toolkit is designed for the task of generating content and presenting data, and it generally leaves more complex issues to a real programming language, namely, Perl.
We have already seen the basics of what a template looks like—a mixture of tags (known as directives) and other fixed text. The template processor interprets the directives and the remaining text is passed through unchanged.
By default, the start and end of a directive are marked by the sequences [% and %], but the TAGS directive can be used to change them if you don't like these. The TAGS directive takes either one or two arguments. The single-argument version expects the name of a predefined tag set. For example, the star set replaces the tag delimiters with [* and *]:
[% TAGS star %]
People of [* planet *], your attention please.
If you give TAGS two arguments, they define the start and end tag markers that you want to use. For example, if you're processing plain text, you might find something like this more lightweight and easier to type:
[% TAGS { } %]
People of {planet}, your attention please.
Or if you are processing HTML and you prefer an HTML style, how about this:
[% TAGS <tt: > %]
<p>People of <tt:planet>, your attention please.
Changes to tags take effect immediately and affect only the current file.
You can also set these from the command line with ttree by using the --start_tag, --end_tag, and --tag_style options. From a Perl script, the corresponding configuration options for the Template module are START_TAG, END_TAG, and TAG_STYLE. For Apache::Template, the TT2Tags option can be used with one or two arguments, as per the TAGS directive.
In the rest of this book, we use the default tag style. We like it because it makes the directives stand out from the surrounding text, rather than making them blend in. We think it makes templates easier to read and write when you can more clearly distinguish one part from another.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Template Variables
The variables that we have used so far have been scalar variables. A scalar variable stores a single piece of information—either a string or a number.
The value of a scalar variable is inserted in a template by using the variable name inside a directive like this:
[% planet %]
A variable wouldn't be worthy of the name if you couldn't also set its value. We have seen examples of doing this using the --define option of the tpage command, but it is also possible to set a variable's value inside a template:
[% planet = 'Magrethea' %]
People of [% planet % ], your attention please.
In addition to scalar variables, the Template Toolkit also supports two complex data types for storing multiple values: the list and hash array (also known as a hash). A list is an ordered array of other variables, indexed numerically and starting at element 0. A hash is an unordered collection of other variables, which are indexed and accessible by a unique name or key.
Perl programmers will already be familiar with these data structures. When you use the Template Toolkit from Perl you can easily define hash arrays and lists that are then passed as template variables to the process( ) method.
Example 1-9 shows a Perl program similar to Example 1-6, which defines a list of friends and a hash of terms as template variables.
Example 1-9. Perl program to process friends.tt
use Template;
   
my $tt    = Template->new( );
my $input = 'friends.tt';
my $vars  = {
    friends => [ 'Ford Prefect', 'Slartibartfast' ],
    terms  => {
        sass  => 'know, be aware of, meet, have sex with',
        hoopy => 'really together guy',
        frood => 'really, amazingly together guy',
    },
];
   
$tt->process($input, $vars)
    || die $tt->error( );
Example 1-10 is the friends.tt template that Example 1-9 processes.
Example 1-10. The friends.tt template
Your friends are:
[% FOREACH friend IN friends -%]
 * [% friend %]
[% END -%]
   
You know the following terms:
[% FOREACH term IN terms.keys.sort -%]
 [% term %]: [% terms.$term %]
[% END -%]
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Template Directives
The examples we have looked at so far have concentrated on the use of variables. The Template Toolkit also provides more advanced language constructs called directives. These begin with an uppercase keyword such as PROCESS, IF, or FOREACH and tell the template processing engine to do something.
Given that directives start with an uppercase keyword, you might be forgiven for thinking that the examples we have seen so far don't count as directives:
[% name = 'Arthur Dent' %]
[% planet = { name = 'Earth' } %]
Welcome [% name %] of [% planet.name %].
However, the syntax that we have been using until now to set and get variables is actually just a convenient shortcut for the full version, which uses the SET and GET keywords like so:
[% SET name = 'Arthur Dent' %]
[% SET planet = { name = 'Earth' } %]
Welcome [% GET name %] of [% GET planet.name %].
For obvious reasons, the shorter versions are used most of the time.
Another use of template directives is for changing the way templates are processed. The PROCESS directive is one of the simplest. It loads another template file, processes the contents, and inserts the generated output in the calling template:
[% PROCESS header %]
The Template Toolkit provides the INCLUDE_PATH option, which allows you to specify one or more directories where your template files can be found. This allows you to specify your templates with simple names such header, rather than full file paths such as /home/dent/templates/lib/header, for example.
The reason that it is called INCLUDE_PATH and not PROCESS_PATH becomes obvious when we mention that there is also an INCLUDE directive. The INCLUDE directive and related INCLUDE_PATH option have been part of the Template Toolkit, and the Text::Metatext module that preceded it, from the very beginning. The PROCESS directive, on the other hand, was added at a later date, and was able to reuse the INCLUDE_PATH option for the same purposes.
The difference between PROCESS and INCLUDE is revealed in Chapter 2. For now it suffices to know that INCLUDE is most often used when you want to pass variable values that should remain local to that one template:
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Integrating and Extending the Template Toolkit
A particular strength of the Template Toolkit is that it doesn't try and do everything by itself. It concentrates on providing features that are generally applicable to template processing, leaving application-specific functionality to be added using Perl.
We've seen how you can define dynamic variables to allow your templates to access subroutines and objects written in Perl. The plugin mechanism allows you to bundle Perl code in self-contained modules that can be loaded straight into a template with a USE directive, eliminating the need to write a Perl wrapper program.
If that isn't enough, you can also define your own filters and virtual methods, and even change the language itself if you're feeling brave. This is covered in Chapter 8.
The fundamental concept that we're trying to get across is that the Template Toolkit is, as the name suggests, a toolkit for building things. It was designed to be easily extended and integrated with other components so that it can work within your requirements. It is not a complete web programming language or content management system that tries to do everything, and thus forces you into its way of thinking and working.
Sometimes that means you've got a little more thinking to do for yourself, rather than just blindly following the One True Way that we could have chosen for you. However, the benefit is that your solutions will be more flexible and adaptable, as well as better suited to addressing the problems at hand.
No two web sites (or document systems in general) are alike. Similarly, no two web developers agree on every issue that presents itself in the design and implementation of a web site. They each have their own ideas about the best way to tackle different problems, and prioritize different concerns according to the unique perspective that their past experience affords them. Perfect solutions don't exist (or if they do, we've never encountered them). With this in mind, strive to build a system that works today and tomorrow, even if it doesn't solve every problem overnight. Know when to compromise ideals for the sake of a pragmatic solution and when to stand firm on the issues that are important.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Chapter 2: Building a Complete Web Site Using the Template Toolkit
This chapter puts the Template Toolkit into context. We show several different ways of using the Template Toolkit to simplify the process of building and managing web site content. We start with some simple examples showing the use of template variables and template components that allow web content to be constructed in a modular fashion. As we progress further into the chapter, we look at more advanced techniques that address the issues of managing the site structure, generating menus and other navigation components, and defining and using complex data.
Although the focus of this chapter is on generating web content, it also serves as a general introduction to the Template Toolkit. It demonstrates techniques that can be adapted to different application areas. This chapter will quickly get you up to speed using the Template Toolkit, but without bogging you down in too much gory detail (we're saving that for the rest of the book). We come back to the Web to look at more advanced examples of static and dynamic web content in Chapter 11 and Chapter 12.
Although we may touch briefly on some more advanced issues, we try not to bore you with too much detail, except where it is absolutely necessary to illustrate a key point or explain an important concept. Chapter 3 discusses the syntax and structure of templates and the use of variables, while Chapter 4 covers the various template directives. More information relating to filters and plugins can be found in Chapter 5 and Chapter 6, respectively. More advanced topics concerning the use of the Template Toolkit for generating web content and interfacing to web applications can be found in Chapter 11 and Chapter 12.
We assume a Unix system in the examples in this chapter, but the principles apply equally well to other operating systems. On a Microsoft Windows machine, for example, the File Explorer can be used to create folders (directories) and shortcuts (symbolic links) using the familiar point-and-click interface. Another option we can highly recommend is to install Cygwin. Cygwin is freely available from http://www.cygwin.com
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Getting Started
Every big web site is made up of individual pages. Let's start with a small and simple page, showing how to eliminate basic repetition using templates. In later sections, we can build on this to generate more pages and add more complex elements.
Example 2-1 shows the HTML markup of a page that displays the customary "Hello World" message, complete with a title, footer, and various other bits of HTML paraphernalia.
Example 2-1. hello.html
<html>
  <head>
    <title>Arthur Dent: Greet the Planet</title>
  </head>

  <body bgcolor="#FF6600">
    <h1>Greet the Planet</h1>

    <p>
      Hello World!
    </p>

    <hr />

    <div align="middle">
      &copy; Copyright 2003 Arthur Dent
    </div>
  </body>
</html>
HTML is relatively straightforward in terms of syntax and semantics. We'll assume that you've got at least a passing aquaintance with the basics of HTML. If you don't, HTML & XML by Chuck Musciano and Bill Kennedy (O'Reilly) provides a definitive guide to the subject.
Although HTML is simple, it does tend to be rather verbose. It's all too easy for the core content of the page to be obscured by the extra markup required around it. There's also some repetition that we would like to avoid. The page title and author's name both appear twice in the same page, for example. We can also assume that other pages in the site will be using similar pieces of data, repeated over and over again in numerous different places.
The author's name, background color, and copyright message are a few examples of items that we would really rather define in just one place in case we ever decide to change them. We don't want to have to edit every page in the site when we need to change the copyright message (at the start of a new year, for example), or decide that blue is the new orange and want to use it as the background color for every page.
We can address these issues by applying the basic principles of template processing. Rather than creating the HTML page directly, we write a template for generating the HTML page. In this document, we use template variables to store these values instead of hardcoding them.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Template Components
Example 2-2 shows a template for generating a complete HTML page. We refer to this kind of template as a page template to distinguish it from the other kind of template that we're now going to introduce: the template component.
We use the term "template component" to help us identify those smaller templates that contain a reusable chunk of text, markup, or other content, but don't constitute complete pages in their own right. Template components are no different from page templates as far as the Template Toolkit is concerned—they're all just text files with embedded directives that need processing and get treated equally. Examples of typical template components include headers, footers, menus, and other user interface elements that you will typically want to use and reuse in different page templates across the site.
When we start using ttree a little later in this chapter, we will need to be more careful about storing our page templates separately from any template components. For now, however, we can keep them all in the same directory, simplifying matters for the purpose of our examples. As a general naming convention, we use a .tt or .html file extension for page templates (e.g., hello.tt), and no extension for component templates (e.g., header), but this is entirely arbitrary. If you want to give them an extension (e.g., header.ttc), that's fine.
Our first components can be created easily. Extract the header and footer blocks from Example 2-2 and save them in their own header and footer template files, as in Examples Example 2-3 and Example 2-4.
Example 2-3. header
<html>
  <head>
    <title>[% author %]: [% title %]</title>
  </head>

  <body bgcolor="[% bgcol %]">
    <h1>[% title %]</h1>
Example 2-4. footer
    <hr />

    <div align="middle">
      &copy; Copyright [% year %] [% author %]
    </div>
  </body>
</html>

Section 2.2.1.1: The PROCESS directive

We can now load these template components into a page template using the PROCESS directive. Example 2-5 shows this in action.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Defining Variables
Our current use of tpage for processing templates is hardly streamlined. We're spending a lot of time typing variable values on the command line, something that can only get worse as we add more pages that require processing to the site.
It would be easy to mistype the value for a variable, for example, or perhaps supply the wrong value altogether. You wouldn't see any complaint from the Template Toolkit. It would just go right ahead and process the template with whatever values you supplied, possibly leading to an error on an HTML page that could go unnoticed.
A better approach is to create a template component that defines any commonly used variables in one place. Example 2-7 shows our config template.
Example 2-7. config
[%  author = 'Arthur Dent'
    bgcol  = '#FF6600'    # orange
    year   = 2003
    copyr  = "Copyright $year $author"
-%]
You can define any number of variables in a single directive, as Example 2-7 illustrates. The Template Toolkit is very flexible in terms of the syntax it supports inside its tags, allowing you to spread your directives over several lines, adding as little or as much whitespace as you like for formatting purposes. You don't need to put each on a separate line as we have here—they can all go on the same line as long as some kind of whitespace is separating them. In the end, it's your choice. The Template Tooolkit isn't fussy about how you lay out your directives, as long as you follow the basic rules of syntax, which we'll be introducing throughout this chapter and describing in greater detail in Chapter 3.

Section 2.3.1.1: Comments

You can add comments to annotate your code, as shown in the second line of Example 2-7: # orange. A comment starts with the # character and continues to the end of the current line. The comment is ignored by the Template Toolkit, and processing continues as normal on the next line.
If # is used as the first character immediately following the opening [% tag, the Template Toolkit ignores the entire directive up to the closing
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Generating Many Pages
The tpage program is fine for processing single templates, but isn't really designed to handle the many pages that comprise a typical web site. For this, ttree is much more appropriate. It works by drilling down through a source directory of your choosing, looking for templates to process. The output generated is saved in a corresponding file in a separate destination directory.
In addition to working well with a large number of template files, ttree also provides a much greater range of configuration options that allow you to modify the behavior of the Template Toolkit when processing templates. This allows you to further simplify the process of generating and maintaining web content in a number of interesting ways that we'll explore throughout this section.
Our templates will need to be organized a little more carefully when using ttree. In particular, we need to separate those page templates that represent complete HTML pages (hello.tt, goodbye.tt, earth.tt, and magrethea.tt in our previous examples) from those that are reusable template components (config, header, and footer).
We'll start by creating a directory for our web site, complete with subdirectories for the source templates for HTML pages (src), a library of reusable template components (lib), and the generated HTML pages (html). We'll also create a directory for miscellaneous files (etc), including a configuration file for ttree, and another (bin) for any scripts we accrue to assist in building the site and performing maintenance tasks.
$ cd /home/dent
$ mkdir web
$ cd web
$ mkdir src lib html etc bin
Now we need to define a configuration file for ttree. Example 2-10 shows an example of a typical etc/ttree.cfg file.
Example 2-10. etc/ttree.cfg
# directories
src  = /home/dent/web/src
lib  = /home/dent/web/lib
dest = /home/dent/web/html

# copy images and other binary files
copy = \.(png|gif|jpg)$

# ignore CVS, RCS, and Emacs temporary files
ignore = \b(CVS|RCS)\b
ignore = ^#

# misc options
verbose
recurse
Options can appear in any order in the configuration file. In certain cases (such as
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Adding Headers and Footers Automatically
In addition to the fact that ttree works well with large collections of page templates, it also has the benefit of providing a large number of configuration options that allow you to change the way it works and how it uses the underlying Template Toolkit processor. Two of the most convenient and frequently used options are pre_process and post_process. These allow you to specify one or more templates that should be automatically added to the top or bottom of each page template, respectively. This can be used to add standard headers and footers to a generated page, but pre- and postprocessed templates may not generate any visible output at all. For example, we can use a preprocessed template to configure some variables that we might want defined for use in the page template or other template components.
The following can be added to the bottom of the etc/ttree.cfg file to have the config and header templates preprocessed (in that order so that we can use variables defined in config in the header) and the footer template postprocessed:
pre_process  = config
pre_process  = header
post_process = footer
Now the page templates can be made even simpler, as Example 2-12 shows.
Example 2-12. src/magrethea.html
[% title = 'Magrethea' -%]

<p>
  Home of the custom-made 
  luxury-planet building industry.
</p>
Remember that you'll need to use the -a option to force ttree to rebuild all pages in the site to have the changes take effect:
$ bin/build -a
There is one problem with this approach. The header template is processed in its entirety before the main page template gets a look in. This means that the title variable isn't set to any value when the header is processed. It doesn't get set until the page template is processed, by which time it's too late for the header to use it.
The Template Toolkit won't complain if it encounters a variable for which it doesn't have a value defined. Instead, it will quietly use an empty string (i.e., nothing at all) for the value of the variable and continue to process the remainder of the template. The
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
More Template Components
You can create any number of different reusable template components to help you generate the content for your web site. Whenever you find yourself repeating the same, or a similar, block of markup in more than one place, you might want to consider moving it into a separate template file that you can then use and reuse whenever you need it. This not only saves you a lot of typing, but also ensures that the HTML generated in each place you use it is identical, or as near to identical as you would like it to be, accounting for any variables that might change from one use to the next.
Example 2-15 shows a template component for displaying an entry from Arthur's favorite reference book.
Example 2-15. lib/entry
<p>
  The Hitch Hiker's Guide to the Galaxy
  has this to say on the subject of
  "[% title %]".
</p>

<table border="0">
  <tr valign="top">
    <td>
      <b>[% title %]:</b>
    </td>
    <td>
      [% content %]
    </td>
  </tr>
</table>
The template uses two variables, title and content. The value for title can in this case be copied from template.title, thereby providing the title set in the META directive for the page. A value for content will be set explicitly for the sake of simplicity. These variables can be set either before the PROCESS directive:
[% title   = template.title
   content = 'Mostly harmless'
%]

[% PROCESS entry %]
or as part of the PROCESS directive, following the template name as additional arguments:
[% PROCESS entry
     title   = template.title
     content = 'Mostly harmless'
%]
The end result is the same. The Template Toolkit treats all variables as global by default so that you can define a variable in one template and use it later in another without having to explicitly pass it as an argument every time. In both of the preceding examples, the title and content variables are defined globally and can subsequently be used in both the called template (entry) and the calling template (earth.tt) after the point of definition.
In the following fragment, for example, the reference to the content variable at the end of the template will generate the value "Mostly harmless" as set in the earlier
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Wrapper and Layout Templates
Now it's time to bring out some of the bigger guns of the Template Toolkit. The WRAPPER directive and layout templates let you define a common look for web pages in a single file, rather than scattering the components over header and footer files.
The entry template from Example 2-15 works well when the content to be displayed is relatively simple. However, it quickly becomes cumbersome for longer entries such as the one shown here:
[% INCLUDE entry
     title   = 'Vogon Poetry'
     content = 'Vogon poetry is of course the 
                third worst in the Universe.  
                The second worst is that of...

                ...etc...

                ...in the destruction of the 
                planet Earth'
%]
Special care must be taken when quoting content that contains quote characters. Consider the following extract that illustrates this problem:
Grunthos is reported to have been "disappointed" 
by the poem's reception.
If this is enclosed in single-quote characters, the apostrophe in "poem's" must be escaped by preceding it with a backslash \ character (the apostrophe and single-quote characters are one and the same for these purposes):
[% INCLUDE entry
     title   = 'Grunthos the Flatulent'
     content = 'Grunthos is reported to have 
                been "disappointed" by the 
                poem\'s reception.'
%]
Another alternative is to use double quotes to define the variable, allowing single quotes to remain as they are. But in this case, any occurrences of double quotes will then need to be escaped:
[% INCLUDE entry
     title   = 'Grunthos the Flatulent'
     content = "Grunthos is reported to have 
                been \"disappointed\" by the 
                poem's reception."
%]
A better solution is to use the WRAPPER directive. It works in a similar way to INCLUDE, but uses an additional END directive to enclose a block of template content. The WRAPPER directive uses this block as the value for the content variable:
[% WRAPPER entry
     title = 'Grunthos the Flatulent'
%]
   Grunthos is reported to have 
   been "disappointed" by the 
   poem's reception.
[% END %]
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Menu Components
In the layout template in Example 2-20, we delegate the task of generating a menu for the web site to the menu template. Before we look at how the template does this, let's see an example of the kind of HTML that we would like it to generate.
<table border="0">
  <tr>
    <td>
      <img src="/images/icon.png" width="4" height="4" />
    </td>
    <td>
      <a href="earth.html">Earth</a>
    </td>
  </tr>
  <tr>
    <td>
      <img src="/images/icon.png" width="4" height="4" />
    </td>
    <td>
      <a href="magrethea.html">Magrethea</a>
    </td>
  </tr>
</table>
The entire menu is defined as a <table> element, containing one <tr> row for each item, each of which holds two <td> cells, one to display an icon, the other a link to a particular page. Only two items are in this simple example, but already we can see how it gets repetitive very quickly. This suggests that we can modularize the markup into separate template components.
Example 2-23 shows a menu template that defines the outer <table> elements and uses a second template, menuitem, to generate each item.
Example 2-23. lib/menu
<table border="0">
[%
 PROCESS menuitem
  text = 'Earth'
  link = 'earth.html';

 PROCESS menuitem
  text = 'Magrethea'
  link = 'magrethea.html';
%]
</table>

[% BLOCK menuitem %]
<tr>
  <td>
    <img src="/images/icon.png" width="4" height="4" />
  </td>
  <td>
    <a href="[% link %]">[% text %]</a>
  </td>
</tr>
[% END %]

Section 2.8.1.1: The BLOCK directive

We could easily define the menuitem template in a separate file as we have with other components, but it would require us to split the HTML <table> markup into different files. This would make it harder to maintain and possibly lead to tag mismatch or other formatting errors.
Instead, we define the menuitem template inside the menu template using the BLOCK directive. The argument following the BLOCK keyword is a name for the template component, which can then be used in any PROCESS, INCLUDE, or WRAPPER directives. The content of the component follows, and can contain any kind of Template Toolkit directives up to the corresponding
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Defining and Using Complex Data
The variables that we have used so far have mostly been simple scalar variables that contain just one value. The few exceptions include the tantalizing glimpses of the template variable, and the Date plugin in Example 2-22. As we saw in Chapter 1, the Template Toolkit also supports lists and hash arrays for complex data, and allows you to access Perl subroutines and objects.
In this section, we will look more closely at defining and using complex data structures, and describe the different Template Toolkit directives for inspecting, presenting, and manipulating them.
Larger sites will typically use dozens of different global site variables to represent colors, titles, URLs, copyright messages, and various other parameters. The Template Toolkit places no restriction on the number of different variables you use, but you and your template authors may soon lose track of them if you have too many.
Another problem with having lots of global variables lying around is that you might accidentally overwrite one of them. We saw in Example 2-7 how the author variable was used to store the name of the site author, Arthur Dent, for use in the header and footer templates. At some later date, we might decide to add a quote template component that also uses the author variable. This is shown in Example 2-28.
Example 2-28. lib/quote
<blockquote>
  [% quote %]
</blockquote>

  -- [% author %]
There's no problem if we use INCLUDE to load the template, providing a local variable value for author:
[% INCLUDE quote
     author = 'Douglas Adams'
     quote  = 'I love deadlines. I like the
               whooshing sound they make as 
               they fly by.'
%]
The value for author supplied as a parameter to the INCLUDE directive (Douglas Adams) remains set as a local variable within the quote template. It doesn't affect the global author variable that is defined in the config (Arthur Dent).
However, it is all too easy to forget that the author variable is "reserved"—especially if it's just one of a large number of such variables—and to use PROCESS instead of
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Assessment
This brings us nicely back to where we started, looking at the basic principle of template processing: separating your data from the way it is presented. It's not always clear where your data belongs: in a configuration template; defined in a Perl script; or perhaps stored in a SQL database or XML file. Sometimes you'll want to begin by defining some simple variables in a configuration template so that you can start designing the layout and look and feel of the site. Later on, you might choose to define that data somewhere else, passing it in from a Perl script or making it available through a plugin.
The beauty of the Template Toolkit is that it really doesn't matter. It abstracts the details of the underlying implementation behind the uniform dotted notation for accessing data so that your templates keep working when your storage requirements change, as they inevitably will for many web sites.
It also makes it easy to include things such as loops, conditional statements, and other templates as easy as possible so that you can concentrate on presentation, rather than getting bogged down in the more precise details of full-blown programming language syntax. This is what we mean when we describe the Template Toolkit as a presentation language rather than a programming language.
It is an example of a domain-specific language that in many ways is similar to SQL, which is a domain-specific language for formulating database queries. As such, it should generally be used for what it is good at, rather than being contorted into doing something that might be a lot easier in another language. That doesn't mean that you can't use the Template Toolkit to do CGI programming, embed Perl, or even write Vogon poetry, if that's your thing, but that's not necessarily where its particular strengths lie.
And that's where Perl comes in. The Template Toolkit is designed to integrate with Perl code as cleanly and as easily as possible. When you want to do something more than the Template Toolkit provides, it is easy to append your own additions using a real programming language such as Perl. The plugin mechanism makes it easy to load external Perl code into templates so that you're not always writing Perl wrapper scripts just to add something of your own.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Chapter 3: The Template Language
While a programming language is designed to manipulate data, a presentation language is used to turn the data into plain text, HTML, or some other format. As long as the data is made available to us in a textual representation when we ask for it, we really don't need to worry too much about how it is stored or computed behind the scenes.
That's not to say that you can't create and manipulate variables in templates. However, their most common use is for dealing only with presentation aspects, by using variables to define colors or other layout parameters, displaying the first N search results, or sorting a list of names into alphabetical order, for example. It is unusual (but not unheard of) to use the Template Toolkit to modify data that has any lasting effect. In general, data is passed to a template and then thrown away, so it doesn't matter if it's changed in any way.
In this chapter, we take a closer look at the details of the Template Toolkit presentation language. The general syntax of templates comes under scrutiny first, and we give examples of how the default style can be customized using configuration options and template directives. The rest of the chapter is then dedicated to an in-depth study of variables. We describe the various data types, showing how they are defined and used in both Perl and template markup.
We concentrate on the general characteristics of the language without looking too closely at any of the specific directives that the Template Toolkit provides (PROCESS, WRAPPER, USE, and so on). These are described in detail in Chapter 4. A full discussion of filters and plugins is left for Chapter 5 and Chapter 6, respectively.
While you can write templates that have a lasting effect on data—say, by updating a database directly—that's not really how the Template language was intended to be used. We return to this subject in Chapter 11 and Chapter 12, when we look more closely at separating the functional parts of an application from those that deal only with presentation.
The Template Toolkit has many configuration options to change the appearance and meaning of the directives in a template. This section looks at the different types of directives, shows how to change the directive tags, and describes the various ways you can control the processing of whitespace around directives.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Template Syntax
The Template Toolkit has many configuration options to change the appearance and meaning of the directives in a template. This section looks at the different types of directives, shows how to change the directive tags, and describes the various ways you can control the processing of whitespace around directives.
A template contains a mixture of fixed text and directive tags, denoted by the [% and %] markers. Everything coming after the [% and before the following %] is part of the directive tag. Everything else in the document is fixed text that is passed through intact.
Well, that's the default behavior, anyway. There are certain occasions when the text surrounding directives will be modified. For example, the whitespace chomping options (PRE_CHOMP and POST_CHOMP) and related flags (which we'll be looking at shortly) tell the Template Toolkit to remove any extraneous whitespace in the text on either side of (i.e., before or after) a directive. The INTERPOLATE option is another example that, when set (which it isn't by default), causes the text part of the template to be passed through a second scanning process to look for any embedded variables, denoted by a $ prefix—e.g., Hello $planet. More on that later.