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.

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.

Process the same template a few thousand times with different sets of data and you have the entire basis of the junk-mail industry. Or a Vogon Constructor Fleet.

This book is a good example of a more complex template. All O’Reilly books conform to one of a small number of formats. They all have similar sets of front matter (title page, publication information, table of contents, and preface), followed by the actual chapters, some (optional) appendices, an index, and finally the colophon. Templates that define the look of all of these parts are defined in the publication system, and the data for a particular book is formatted to conform to those rules. If someone decides to change the font used for the chapter titles in forthcoming books, he need only change the setting in the template definition.

Another way to look at a template processor is as a tool for separating processing from presentation. For example, a company sales report is probably created from data stored in a database. One way to create the report would be to extract the required data into a spreadsheet and then do calculations on the data to produce the information required. The spreadsheet could then be printed out or emailed to the required recipients.

Although you can use templates to generate any kind of text document, the most common use is to generate HTML pages for web content. The whole genre of template processing systems has matured rapidly in less than a decade, particularly within the Perl community, in response to the demands of people struggling to build and maintain ever more complex content and applications for their web sites.

Templates help in a number of ways. The most obvious benefit is that they can be used to apply a consistent look and feel to all the pages in a web site to achieve a common branding. You can use a template to add standard headers, footers, menus, and other user interface components as easily as the Hyperspace Planning Council ruthlessly adds a few lines of Vogon poetry to every planet destruction order, just to rub salt into the wounds.

This is just the tip of the iceberg. In addition to the use of variables, the Template Toolkit provides a number of other directives that instruct it to perform more complex processing actions, such as including another template, repeating a section of markup for different pieces of data, or choosing a section to process based on a particular condition. Example 1-3 illustrates some of these directives in action.

Example 1-3. Loops, conditions, and processing instructions in a template
[% FOREACH order IN council.demolition.orders %]    
   [% PROCESS header %]
 
   [% IF order.destruction %] 
     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.
   [% ELSE %]
      Our representatives will be visiting your
      star system within the next few weeks, 
      and would like to invite you to a reading of
      Vogon Poetry. Attendance is mandatory.  
      Resistance is useless!
   [% END %] 
 
   [% PROCESS footer %]
   
   [% PROCESS poetry/excerpt
           IF today.day =  = 'Vogonsday'
   %]
[% END %]

We explain the purpose of these directives later in this chapter, and show examples of the different ways they can be used throughout the rest of the book. For now, you can probably work out what they do from their names.

The Template Toolkit is just one example of a template processor. Although it’s written in Perl, you don’t actually need to know any Perl to use it. The presentation language that it provides is intentionally simple, regular, and easy to understand and use. This makes it simple for web designers and other nonprogrammers to use it without first having to get to grips with Perl. The Template Toolkit provides language features and off-the-shelf plugin modules that allow you to perform many common tasks, including CGI programming, manipulating XML files, and accessing SQL databases.

If you do know Perl, however, you’ll be able to get more out of the Template Toolkit by writing custom functions and extensions to handle the specifics of your particular application. The good news for Perl programmers is that the Template Toolkit allows you to separate Perl code clearly from HTML templates. This clear separation means that you don’t have to wade through pages of HTML markup to find the part of your web application that needs attention. It allows you to concentrate on one thing at a time, be it the HTML presentation or the Perl application, without having the other aspects in your face and under your feet. It makes both your HTML templates and Perl code more portable and reusable, and easier to read, write, and maintain.

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.

HTML::Mason is available from http://www.masonhq.com/ and CPAN (http://search.cpan.org/dist/HTML-Mason/).

HTML::Embperl

Embperl gives you the power to embed Perl code in your HTML documents, and the ability to build your web site out of small reusable objects in an object-oriented style. You can also take advantage of all the usual Perl modules (including DBI for database access), use their functionality, and easily include their output in your web pages.

Embperl has several features that are especially useful for creating HTML, including dynamic tables, form field processing, URL escaping/unescaping, session handling, and more.

Embperl is a server-side tool, which means that it’s browser-independent. It can run in various ways: under mod_perl, as a CGI script, or offline.

HTML::Embperl is available from http://www.ecos.de/ or CPAN (http://search.cpan.org/dist/HTML-Embperl/).

Apache::ASP

Apache::ASP provides an Active Server Pages port to the Apache web server with Perl scripting only, and enables development of dynamic web applications with session management and embedded Perl code. Apache::ASP also provides many powerful extensions, including XML taglibs, XSLT rendering, and new events not originally part of the ASP API.

Apache::ASP is available from CPAN (http://search.cpan.org/dist/Apache-ASP/).

The Template Toolkit attempts to offer the best features of these modules, including separation of Perl from templates and applicability beyond HTML.

The Template Toolkit Is for More Than HTML

The Template Toolkit is a generic template processing system that will process any kind of document for use in any environment or application. Many other template systems were designed specifically to create HTML pages for web content. In some cases, that is all the system can be used for. In others, it is possible (with varying degrees of difficulty) to use the system in a non-web environment.

The Template Toolkit was originally designed to help Andy create his web site, but he was careful to ensure that it was just as usable outside of that environment. As a result, there is nothing within the Template Toolkit that assumes it is being used to generate HTML. It is equally at home creating any other kind of data.

The Template Toolkit Lets You Choose Your Separation

Template Toolkit doesn’t prescribe any particular methodology or framework that forces you to use it in a certain way. Some modules (for example, HTML::Template) enforce a very strict interpretation of template processing that intentionally limits what can be done in a template to accessing variables and using simple conditional or looping constructs. Others (such as HTML::Mason and HTML::Embperl) use embedded Perl code to allow any kind of application functionality to be incorporated directly into the templates.

The Template Toolkit gives you the best of both worlds. It has a powerful data engine (the Stash) that does all the hard work of mapping complex data structures from your Perl code, configuration files, SQL databases, XML files, and so on, into template variables that are accessed by a simple and uniform dotted notation (e.g., person.surname). You can use this to keep your templates simple without limiting the complexity or functionality of the systems that put data into the templates.

At the opposite end of the spectrum, the Template Toolkit also allows you to embed Perl code directly in your templates. We don’t normally encourage this because it tends to defeat the purpose of having a template processing system in the first place. Because this is the exception rather than the norm, template processors must set the EVAL_PERL option to embed Perl code in the template (it is disabled by default). We look at how to set options later in this chapter.

Template Toolkit also lets you work between the two extremes. It provides a rich set of language features (directives) that allow you to add complex functionality to your templates without requiring you to embed Perl code. It also has a powerful plugin mechanism that allows you to load and use Perl modules to extend the functionality in any way you can imagine.

In short, the Template Toolkit allows you to take a modular approach to building your web site or other document system, but doesn’t enforce it. Sometimes you want to build a complex and highly structured system to run a web site. Other times you just want to roll up a quick all-in-one template to generate a report from a database. The Template Toolkit encourages whatever approach is most appropriate to the task at hand.

Nonprogrammers Can Maintain Templates

Template Toolkit’s template language is designed to be as simple as possible without being too simple. The dotted notation makes accessing variables far less daunting than in Perl. For example:

$person->{surname}   # Perl
person.surname       # Template Toolkit

This hides the underlying implementation details from the template designer. In the previous example, the Perl syntax implies that $person is a reference to a hash array containing a surname value. However, you might one day decide to implement $person as an object with a surname( ) method:

$person->surname( )   # Perl
person.surname       # Template Toolkit

The Perl code requires a different syntax but the Template Toolkit code stays the same. This lets you change the underlying implementation at any time without having to change the templates. As long as the data is laid out in the same way (i.e., don’t change surname to last_name), it doesn’t really matter what data structures are used, or whether they are precomputed, fetched from a database, or generated on demand.

This uniform syntax also means that your template designers can remain blissfully ignorant of the difference between a hash array and an object. They don’t have to worry about any confusing syntax and can concentrate on the task at hand of presenting the data nicely. This makes the template language as friendly as possible for people who aren’t already Perl programmers.

The general rule is to use Perl for programming and the Template Toolkit for presentation. But again, it’s not mandatory, so you’re still free to bend (or break) the rules when you really need to.

The Template Toolkit Is Easy to Extend

The Template Toolkit is designed to be easy to extend. If it doesn’t already do what you want, there’s a good chance you can reimplement a small part of it to change it to do what you what. The object-oriented architecture of the Template Toolkit makes this process relatively straightforward, and there are programming hooks throughout the system to give you as much flexibility as possible.

A number of plugins exist for the Template Toolkit, and we cover them in Chapter 6. They are designed to give templates convenient control over things such as HTML tables, database connections, and CGI parameters.

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.

Downloading

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

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 perl Makefile.PL. Run perl Makefile.PL TT_HELP to get the following full list of options:

The following options can be specified as command-line 
arguments to 'perl Makefile.PL'.  e.g.,
   
  perl Makefile.PL TT_PREFIX=/my/tt2/dir TT_ACCEPT=y
   
  TT_PREFIX      installation prefix     (/usr/local/tt2)
  TT_IMAGES      images URL              (/tt2/images)
  TT_DOCS        build HTML docs         (y)
  TT_SPLASH      use Splash! for docs    (y)
  TT_THEME       Splash! theme           (default)
  TT_EXAMPLES    build HTML examples     (y)
  TT_EXTRAS      install optional extras (y)
  TT_XS_ENABLE   Enable XS Stash         (y)
  TT_XS_DEFAULT  Use XS Stash by default (y)
  TT_DBI         run DBI tests           (y if DBI installed)
   
  TT_LATEX       install LaTeX filter    (y if LaTeX found)
  TT_LATEX_PATH      path to latex       (system dependant)
  TT_PDFLATEX_PATH   path to pdflatex    (  "     "     " )
  TT_DVIPS_PATH      path to dvips       (  "     "     " )
   
  TT_QUIET       no messages             (n)
  TT_ACCEPT      accept defaults         (n)
   
By default, the Makefile.PL runs in interactive mode, 
prompting for confirmation of the various configuration
options.  Setting the TT_ACCEPT option causes the default
value (possibly modified by other command line options)
to be accepted.  The TT_QUIET option can also be set to
suppress the prompt messages.

The make test step is important, especially if you’re using a developer release or version from CVS. Over 2,000 tests are provided with the Template Toolkit to ensure that everything works as expected, and to let you know about any problems that you might have. It takes no more than a minute or so to run the tests, and they can save you a great deal of debugging time in the unlikely event that something is wrong with your installation.

Test failures don’t necessarily indicate that something is fatally wrong. A serious problem causes nearly all of the tests to fail, although we haven’t heard of that happening to anyone for quite some time. More often than not, errors raised in the test suite come from plugin modules whose external Perl modules are not installed on your system or are the wrong version.

This kind of problem is rarely serious. At worst, it may mean that a particular plugin doesn’t work as expected—or at all—but that won’t stop the rest of the Template Toolkit from doing its job. You can usually solve the problem by installing the latest version of any dependent modules. If you are unsure about whether a particular test failure is significant, ask on the mailing list, or check the mailing list archives mentioned in Section 1.4.3, later in this chapter. Major problems tend to be reported by many people.

The README and INSTALL files in the Template Toolkit distribution directory provide further information about running the test suite and what to do if something goes wrong.

Documentation and Support

In this section, we take a look at the support that is available for the Template Toolkit.

Viewing the Documentation

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.

Overview of the Documentation

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.

Template::Manual::Intro

A brief introduction to using the Template Toolkit. Not unlike this chapter.

Template::Manual::Syntax

The syntax, structure, and semantics of the Template Toolkit directives and general presentation language. Chapter 3 covers this aspect.

Template::Manual::Variables

A description of the various ways that Perl data can be bound to variables for accessing from templates. Chapter 3 also has the details.

Template::Manual::Directives

A reference guide to all Template Toolkit directives, with examples of usage. See Chapter 4.

Template::Manual::VMethods

A guide to the virtual methods available to manipulate Template Toolkit variables. These are also covered in Chapter 3.

Template::Manual::Filters

A guide to the various standard filters that are supplied with the Template Toolkit. See Chapter 5.

Template::Manual::Plugins

A guide to the various standard plugins that are supplied with the Template Toolkit. See Chapter 6.

Template::Manual::Internals

An overview of the internal architecture of Template Toolkit. See Chapter 7.

Template::Manual::Config

Details of the configuration options that can be used to customize the behavior and extend the features of the Template Toolkit. This is covered in the Appendix.

Template::Manual::Views

A description of dynamic views—a powerful but experimental feature in the Template Toolkit. The use of views is covered briefly in Chapter 9.

Template::Tutorial

An introduction and table of contents to the tutorials that are distributed with Template Toolkit. Currently there are two. Template::Tutorial::Web is a quick start to using the Template Toolkit to create web pages, and Template::Tutorial::Datafile is a guide to creating datafiles in various formats (particularly XML). See Chapter 2 and Chapter 10 for more information about using the Template Toolkit to generate web pages and XML, respectively.

Template::Library::HTML and Template::Library::Splash

Two guides to using libraries of user interface components (widgets) for creating HTML with the Template Toolkit.

Template::Modules

A list of the various Perl modules that make up the Template Toolkit. Each module has its own manual page.

Accessing the Mailing List

If you can’t find the answer to your questions in any of the documentation, you can always turn to the mailing list set up for discussion of the Template Toolkit. You can subscribe to the mailing list at: http://template-toolkit.org/mailman/listinfo/templates. All previous posts are archived at: http://template-toolkit.org/pipermail/templates.

Activity on the list is moderate (around 100 messages per month) and many of the Template Toolkit experts are on the list.

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.

tpage

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

The tpage program is ideal for simple template processing such as this, where nothing more is required than the ability to insert a few variable values. More complex tasks need the ttree program or custom programs using the Template module.

However, there is one last tpage trick we can show you. If you don’t provide tpage with the name of a template file, it reads it from STDIN. This allows you to use it as Unix-style pipeline filter. For example, if the output of the mktemplate program is a Template Toolkit template, the following command can be used to pipe it into tpage to have it processed:

$ mktemplate | tpage

Invoking tpage by itself, with no arguments and no piped input, starts it in interactive mode. In this case, tpage sits and waits for you to type in a source template. This can be very useful for trying out small snippets of template syntax to see what they do.

Here’s an example:

$ tpage
[% subject = 'cat'
   object  = 'mat'
%]
The [% subject %] sat on the [% object %].
^D
The cat sat on the mat.

The first line invokes tpage from the command line. The next three lines are the body of the template in which we type, followed by the end-of-file (EOF) character telling tpage that we’re done. On Unix systems, this is Ctrl-D, shown in the example as ^D. On Microsoft Windows platforms, Ctrl-Z is the EOF character.

The rest of the example shows the output generated by tpage from processing the template. The cat is sitting on the mat, and everything is working as expected.

ttree

The ttree program offers many more features and options than tpage does. The first major difference is that ttree works with entire directories of templates rather than with single files. If you’re using the Template Toolkit to build a web site, for example, you can point ttree at a directory of source templates to process them all, saving the generated HTML pages to corresponding files in an output directory.

The following example shows how you could invoke ttree to process all the templates in the templates directory (containing the files cat and dog for the purpose of this example), and save the generated output in files of the same name, which are located in the output directory:

$ ttree -s templates -d output -v

The -s option defines the source directory for templates, and -d defines the destination directory for output files. The -v (verbose) option causes ttree to print a summary of what it’s doing to STDERR.

Here’s an example of the kind of information generated by the -v option:

ttree 2.63 (Template Toolkit version 2.10)
   
      Source: templates
 Destination: output
Include Path: [  ]
      Ignore: [  ]
        Copy: [  ]
      Accept: [ * ]
   
  + dog
  + cat

This is a summary of the processing options, including the Source and Destination that we provided as the -s and -d command-line options. The dog and cat files are listed as the two files that ttree found in the templates directory. The + characters indicate that both files were successfully processed, creating dog and cat files in the output directory.

Now that these templates have been processed, ttree will not process them again until they are modified or the corresponding output file is deleted. By looking at the file modification times of the source template and destination file, ttree can decide which templates have changed and which have not. It saves time by processing only those that have changed.

If you run the same ttree command again, you see that the + characters to the left of the filenames have changed to - characters:

ttree 2.63 (Template Toolkit version 2.10)
   
      Source: templates
 Destination: output
Include Path: [  ]
      Ignore: [  ]
        Copy: [  ]
      Accept: [ * ]
   
  - dog                      (not modified)
  - cat                      (not modified)

These - characters indicate that the template files were not processed this time, with the reason given in parentheses to the right. This can save a great deal of time when building large document systems using templates (e.g., a typical web site) in which only a few pages change at any one time.

The -a option forces ttree to process all templates, regardless of their modification times:

    $ ttree -a

A second benefit of ttree is that it offers numerous options for changing its behavior. Adding a standard header and footer to each page template, for example, is as easy as setting the relevant option:

$ ttree -s templates -d output -v \
>       --pre_process=header \
>       --post_process=footer

The number of options can be overwhelming at first, but in practice, only a few are used on a regular basis. To avoid having to always use the command line to specify options—something that can quickly become cumbersome and error prone, especially if you are using more than a few—ttree allows you to use configuration files to define all the options for a particular web site or other document system. You can then invoke ttree, passing the name of the configuration file using the -f option:

$ ttree -f /home/dent/web/ttree.cfg

Example 1-5 shows a sample ttree configuration file.

Example 1-5. A sample ttree configuration file, ttree.cfg
src  = /home/dent/web/templates
dest = /home/dent/web/html
lib  = /home/dent/web/lib
   
pre_process  = header
post_process = footer
   
verbose

In the configuration file, the -s and -d options are represented by the src and dest options. We also added a lib option (-l on the command line), which tells ttree about an additional library directory where our header and footer templates are found.

Setting up ttree is a little more involved than using tpage, but the effort quickly pays off in the time it saves you. We look at ttree in detail in Chapter 2, showing everything from first-time use through writing and managing configuration files.

The Template Module

Both tpage and ttree use the Template Perl module to do the dirty work of processing templates. As it happens, the Template module doesn’t actually do much in the way of dirty work itself, but delegates it to other modules in the Template Toolkit with exotic names such as Template::Service, Template::Context, Template::Provider, and Template::Stash. The Template module provides a simple interface for using the Template Toolkit from Perl so that you don’t have to worry about the complex underlying functionality that makes it work. Chapter 7 goes into greater detail about what lurks beneath the hood of the Template Toolkit, but for now we cover just the basics.

If you are already a Perl hacker experienced in using modules, the Template manpage gives you an executive summary to get you quickly up to speed. If you’re not a Perl hacker but would like to be, Learning Perl, Third Edition, by Randal Schwartz and Tom Phoenix (O’Reilly) is a good place to start.

However, you don’t need to know any Perl to use the Template Toolkit. Thanks to the tpage and ttree programs, you can build your entire web site or other template-based document system without ever having to write a line of Perl code. Nevertheless, it’s useful to have a basic understanding of how the Template module is used in Perl programs (including tpage and ttree), even if you never plan on using the module. Also, certain features are accessible only through Perl (for example, the ability to define a subroutine to return the value for a variable), so there is a good chance that sooner or later you will want or need those Perl-specific features.

Example 1-6 shows a simple Perl program for processing the destruction.tt template from Example 1-1.

Example 1-6. A Perl program for processing the Vogon form letter template
#!/usr/bin/perl
   
use strict;
use warnings;
use Template;
   
my $tt    = Template->new( );
my $input = 'destruction.tt';
my $vars  = {
    planet  => 'Earth',
    captain => 'Prostetnic Vogon Jeltz',
    time    => 'two of your earth minutes',
};
   
$tt->process($input, $vars)
    || die $tt->error( );

The first line defines the path to the Perl interpreter on your system. This is very much a Unix-specific convention. On a Windows machine, for example, this line is not relevant or required.

In the first block, we enable Perl’s strict and warnings pragmata and then load the Template module:

use strict;
use warnings;
use Template;

Tip

It is good Perl style to include use strict; and use warnings; at the top of every program, or to invoke Perl with the -w switch instead of use warnings; for versions of Perl earlier than 5.6.0. These two precautions will catch many common programming and typographical errors, and warn you about any questionable practices. Perl examples in this book may omit them for brevity, but you should always include them in any nontrivial chunk of code.

The next line creates a new Template object and assigns it to the $tt variable:

my $tt = Template->new( );

We store the name of the template to be processed in the $input variable and define some template variables in $vars:

my $input = 'destruction.tt2';
my $vars  = {
    planet  => 'Earth',
    captain => 'Prostetnic Vogon Jeltz',
    time    => 'two of your earth minutes',
};

Then we invoke the process( ) method against the $tt template object to process the source template:

$tt->process($input, $vars)
    || die $tt->error( );

The name of the source template file, here stored in the $input variable, is passed as the first argument, followed by a reference to a hash array of template variables, defined in $vars.

The process( ) method processes the template and returns a true value to indicate success. The output is printed to STDOUT by default so that you see it scrolling up your screen when you run the program.

If an error occurs, the process( ) method returns false. In this case, we call the error( ) method to find out what went wrong and report it as a fatal error using die. An error can be returned for a number of reasons, such as the file specified could not be found, had embedded directives containing illegal syntax that could not be parsed, or generated a runtime error while the template was being processed.

Template configuration options

We mentioned the --pre_process and --post_process options when using ttree earlier. Now we can see how these are used in the underlying Perl implementation.

Configuration options are passed to the new( ) constructor method as a reference to a hash, as shown in Example 1-7. The Template module expects options to be provided in uppercase, so the options for ttree translate to the PRE_PROCESS and POST_PROCESS options for the Template module. We also set the INCLUDE_PATH option to indicate the location of the source and library templates, which ttree provides from the src (or -s) and lib (or -l) options. These are provided as a reference to a list of the two directory paths.

Example 1-7. Specifying options when processing templates, ttperl3.pl
my $tt = Template->new({
    PRE_PROCESS  => 'header',
    POST_PROCESS => 'footer',
    INCLUDE_PATH => [
        '/home/dent/web/templates',     # src
        '/home/dent/web/lib',           # lib
    ],
});

Now when the process( ) method is invoked against the $tt object, the source template, destruction.tt, will be processed complete with the header and footer added before and after the main page content, respectively. For this example, we are assuming that the destruction.tt template is located in the /home/dent/web/templates directory, and that header and footer can be found in the /home/dent/web/lib directory.

The Template Toolkit provides numerous configuration options. These are described in detail in the Appendix. We describe the useful ones as we encounter them in later chapters.

Apache::Template Module

The Apache::Template module marries the Template Toolkit with the Apache web server. It is distributed separately from the rest of the Template Toolkit and can be downloaded at http://search.cpan.org/dist/Apache-Template/. It requires an Apache installation that includes Doug MacEachern’s mod_perl extension module, details of which can be found at http://perl.apache.org/. For a full discussion of mod_perl, we recommend Practical mod_perl, by Stas Bekman and Eric Cholet (O’Reilly), which contains an appendix dealing specifically with using the Template Toolkit under Apache and mod_perl.

Apache::Template can be configured via Apache’s normal httpd.conf configuration file. Example 1-8 shows an extract of an httpd.conf file that sets the same options as Example 1-7.

Example 1-8. httpd.conf directives to set options with Apache::Template
PerlModule          Apache::Template
   
TT2IncludePath      /home/dent/web/templates
TT2IncludePath      /home/dent/web/lib
TT2PreProcess       header
TT2PostProcess      footer
   
TT2Params           uri env params cookies
TT2Headers          modified length
   
<Files *.tt2>
    SetHandler      perl-script
    PerlHandler     Apache::Template
</Files>

The first section loads the Apache::Template module:

PerlModule          Apache::Template

The next block sets some standard Template Toolkit options:

TT2IncludePath      /home/dent/web/templates
TT2IncludePath      /home/dent/web/lib
TT2PreProcess       header
TT2PostProcess      footer

Apache::Template adopts the Apache convention of using StudlyCaps for the names of configuration options and also adds a unique TT2 prefix. So the Apache::Template options TT2IncludePath and TT2PreProcess, for example, equate to the INCLUDE_PATH and PRE_PROCESS options for the Template module.

The two options that follow are specific to the Apache::Template handler:

TT2Params           uri env params cookies
TT2Headers          modified length

The first, TT2Params , provides a list of items that the handler should automatically extract from the Apache request and make available as template variables. Any template can use the uri, env, params, and cookies variables to access the request URI, environment variables, request parameters, and cookies, respectively. The second directive, TT2Headers , indicates that Last-Modified and Content-Length headers should be automatically added to the response sent to the client.

The final section uses the Apache Files directive to define the files that should be processed as templates:

<Files *.tt2>
    SetHandler      perl-script
    PerlHandler     Apache::Template
</Files>

The SetHandler and PerlHandler directives within the Files block are standard procedure in Apache for binding a mod_perl handler (Apache::Template in this case) to a set of files. With this configuration, the Apache server processes any files with a .tt2 extension using the Apache::Template handler, but continues to deliver pages with any other extensions as static files, or using any other handlers defined for them.

This is a convenient way of mixing static HTML pages with dynamic page templates in any directory that is currently accessible by the Apache web server. If you want to create a static page, use a .html or other appropriate extension. If you want to create a dynamic page from a template, with the appropriate headers and footer added automatically, simply give it a .tt2 extension and leave Apache::Template to take care of it.

If you would rather not open up your entire web server to the Apache::Template module, you can instead use the Location directive.

<Location /tt2/>
    SetHandler      perl-script
    PerlHandler     Apache::Template
</Location>

In this case, only those files located under the /tt2/ URI will be processed through the Apache::Template handler.

There are numerous other Apache configuration directives, all of which are described in the documentation provided with Apache. For a full discussion of the Apache::Template configuration, see the Appendix.

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.

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.

Complex Variables

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 -%]

This is the output generated by Example 1-9:

Your friends are:
 * Ford Prefect
 * Slartibartfast
   
You know the following terms:
 frood: really, amazingly together guy
 hoopy: really together guy
 sass: know, be aware of, meet, have sex with

There will be times when you’re using the Template Toolkit with tpage or ttree and don’t want to have to write a Perl program, however simple, just to use some complex variables. The Template Toolkit allows you to define lists and hash data structures inside templates, using syntax similar (or identical if you prefer) to the Perl equivalents shown earlier.

The simple examples in the sections that follow should give you a flavor of how lists and hash data structures are defined and used in templates. Chapter 3 describes the Template Toolkit language in detail, showing the different variations in syntax that are permitted to satisfy both Perl programmers (who expect => to be used to separate a hash key from a value, for example) and HTML designers (who probably don’t know any different and are just as happy using the simpler =).

Lists

A list variable is defined in a template using the [...] construct. Here’s how we would create the equivalent of the friends list from Example 1-9:

[% friends = [ 'Ford Prefect', 'Slartibartfast' ] %]

List elements are accessed using the dot operator (.). Follow the list name with a dot and then the element number, starting at zero for the first element:

[% friends.0 %]         # Ford Prefect
[% friends.1 %]         # Slartibartfast

It is also possible to access elements from the list using a variable containing an index value. Simply prefix the variable with a $ character:

[% index = 1 %]
[% friends.$index %]    # Slartibartfast

Hashes

A hash is defined in a template using the {...} construct:

[%  terms = {
        sass  = 'know, be aware of, meet, have sex with'
        hoopy = 'really together guy'
        frood = 'really, amazingly together guy'
    }
%]

Each pair of items within the { and } is composed of the key, to the left of the = (or => if you prefer), and the value to the right. Separate pairs of items with commas, although it’s not obligatory. Here is the same template written in a Perlish style:

[%  terms => {
        sass  => 'know, be aware of, meet, have sex with',
        hoopy => 'really together guy',
        frood => 'really, amazingly together guy',
    }
%]

Hash items are also accessed using the dot operator. In this case, the key for the required item is specified after the dot character:

[% terms.hoopy %]    # really together guy

You can also access hash items using a variable that contains a key. Again, the variable name should be prefixed with a $ character:

[% key = 'frood' %]
[% terms.$key %]     # really, amazingly together guy

Nesting list and hash definitions

Lists and hashes can be nested inside each other to create complex data structures:

[% arthur = {
     name    = 'Arthur Dent',
     planet  = 'Earth',
     friends = [
       { name = 'Ford Prefect'
         home = 'Betelgeuse'
         type = 'frood' }
       { name = 'Slartibartfast'
         home = 'Magrethea'
         type = 'hoopy' }
     ]
     terms = {
       sass  = 'know, be aware of, meet, have sex with'
       hoopy = 'really together guy'
       frood = 'really, amazingly together guy'
     }
   }
%]

You can access items buried deep within a nested data structure by chaining together a series of dot operations to create a compound variable:

[% arthur.friends.1.name %] # Slartibartfast

The Template Toolkit works out which dot operators are performing hash lookups (friends and name) and which are performing list lookups (1), and then automatically does the right thing to return the correct value. Comparing this to the equivalent Perl code, the Template Toolkit’s uniform dot operator makes things much clearer:

# TT
arthur.friends.1.name
   
# Perl
$vars->{arthur}->{friends}->[1]->{name}

This illustrates one of the key benefits of using a presentation language like the Template Toolkit for generating content, rather than a programming language such as Perl.[1] When you write a program using a real programming language such as Perl, it’s important to know which variables are scalars and which are lists, hashes, subroutines, objects, and so on. It’s also critical that you use exactly the right kind of syntax relevant to each data type. Otherwise, your program might try to do something that it shouldn’t, possibly corrupting the data, causing the program to exit with an error, or even failing to compile and run in the first place.

However, when you’re writing templates to present your data as HTML pages, or in some other output format, these issues are of less concern. You’re far more interested in how the data is going to be laid out, than in how it is stored or calculated on demand by the underlying Perl code (as we see in the next section). As long as the value for a user’s name, for example, is inserted in the right place in the template when we ask for arthur.friends.1.name, we’re happy. By the time the data is presented as output in a template, it is all text anyway.

You can also used dotted variables as hash keys to reference other variables. The following example shows how this is done using ${ ... } to explicitly scope the range of the second variable name:

[% arthur.terms.${arthur.friends.1.type} %]

The arthur.friends.1.type variable returns the value hoopy, resulting in a final expression equivalent to arthur.terms.hoopy. This ultimately provides us with the value really together guy.

You can use a temporary variable to break this down into smaller pieces. For example:

[% friend = arthur.friends.1 -%]
[% friend.name %] is a [% arthur.terms.${friend.type} %].

This generates the following output:

Slartibartfast is a really together guy.

Dynamic Variables

The examples that we’ve seen so far have used variables to store static values. When you set a variable to contain a scalar value or a reference to a list or hash array, it remains set to that value until the next time you explicitly modify it. Whenever the variable is used, the Template Toolkit simply looks up the current value for the variable and inserts it in the right place.

The Template Toolkit also allows subroutines and objects to be used to create dynamic variables. Each time such a variable is used, the Template Toolkit will call the subroutine or object method bound to it to return an appropriate value. Whereas static variables contain precomputed values, these dynamic variables return values that are recomputed each time they are used.

Example 1-11 shows a Perl program that defines two template variables, one bound to a subroutine, the other to an object.

Example 1-11. Dynamic data in template variables
use Acme::Planet;       # not a real module (yet)
   
my $vars = {
    help => sub {
        my $entry = shift;
        return "$entry: mostly harmless";
    },
    planet => Acme::Planet->new( name => 'Earth' ),
};

In this example, the help variable is a reference to a subroutine that expects a single argument, $entry. The planet variable references a hypothetical Acme::Planet object. This isn’t a real module (at the time of this writing), but we’re assuming that the new constructor method creates an Acme::Planet object against which we can invoke the name( ) method to return the value provided, Earth.

The following extract shows how these variables can be used in a template:

The guide has this to say about [% planet.name %].
  [% help(planet.name) %]

This would generate the following output:

The guide has this to say about Earth.
  Earth: mostly harmless

Notice that when we call the name method on planet we use the dot operator in exactly the same way as we would if planet were a hash with a key called name. The Template Toolkit doesn’t care which of these we have, it just looks at the variable and works out what is the right thing to do. This illustrates how you are not tied down to any particular implementation for your underlying data structures, and can freely change from hashes to objects and back again without affecting the templates that use them.

Dynamic variables must be defined in Perl. There is no easy or clean way to define dynamic variables from within a template, other than by enabling the EVAL_PERL configuration option and using embedded Perl. The preferred solution is to write a simple Perl script that defines the relevant subroutines, objects, and other data items and then processes the appropriate template or templates. Another approach is to write a Template Toolkit plugin that encapsulates the Perl code and can be loaded into any template on demand. We look at plugins in detail in Chapter 6.

Virtual Methods

The Template Toolkit provides virtual methods for manipulating and accessing information about template variables. For example, the length virtual method can be applied to any scalar variable to return its string length in characters. The virtual method is applied using the dot operator:

[% name = 'Slartibartfast' %]
[% name %]'s name is [% name.length %] characters long.

This generates the output:

Slartibartfast's name is 14 characters long.

Virtual methods are provided for the three main variables types: scalars, lists, and hashes. The following example shows the join list virtual method being used to return the elements in a list joined into a single string. It adds a single space character between each item in the list by default, but you can provide a different delimiter by passing it as an argument in parentheses.

[% friends = [ 'Andy', 'Darren', 'Dave'] %]
Your friends are [% friends.join(', ') %].

This will display:

Your friends are Andy, Darren, Dave.

Some virtual methods alter the contents of the variable that they act on. For example, the pop method removes the last item from a list and returns it:

[% last = friends.pop %]
Your friends are [% friends.join(', ') %] and [% last %].

This will display:

Your friends are Andy, Darren and Dave.

We saw an example earlier of how virtual methods were combined in a dotted variable:

You know the following terms:
[% FOREACH term IN terms.keys.sort -%]
 [% term %]: [% terms.$term %]
[% END -%]

The part that we’re particularly interested in is this:

terms.keys.sort

The terms variable contains a reference to a hash. The keys hash virtual method returns a reference to a list of the keys in the hash. The keys aren’t returned in any particular order, but now that we have a list, we can go on to call the sort list virtual method to return a second list containing the items sorted in alphabetical order.

We can then go one step further and call the join virtual method on that list, to join the items into a single string:

[% terms.keys.sort.join(', ') %]

This generates the following output:

frood, hoopy, sass

Virtual methods are covered in detail in Chapter 3.

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.

Variable Directives

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.

Template Processing Directives

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:

[% INCLUDE header
     title = 'Vogon Poetry'
%]

The Template Toolkit is quite relaxed about how you lay out directives. You can add as little or as much whitespace as you like (including newlines) to help make your directive more readable. The only rule is that you must separate individual words and phrases in the directive (e.g., the INCLUDE keyword and the header template name that follows it) with at least one whitespace character. You don’t need any spacing between the opening tag and the start of the directive, or between the end of the directive and the closing tag, but we recommend it to help make directives easier to read.

The following examples are all valid and equivalent ways of writing the same directive:

[%INCLUDE header title='Vogon Poetry'%]
   
[% INCLUDE header title='Vogon Poetry' %]
   
[% INCLUDE header
      title = 'Vogon Poetry'
%]

Loops

The FOREACH directive allows you to create loops, where a block of template content is processed, once for each item in a list. Here’s the general form:

[% FOREACH item IN list %]
   block of template content...
   ...can contain directives...
   ...and reference the [% item %] variable...
[% END %]

We’ve already seen a real example of this in action:

You know the following terms:
[% FOREACH term IN terms.keys.sort -%]
 [% term %]: [% terms.$term %]
[% END -%]

We know from looking at virtual methods earlier that the terms.keys.sort variable returns a list of the items frood, hoopy, and sass. So our loop block will be repeated three times, with the term variable set to each of those values in turn. We print the term followed by its definition, fetched from the terms hash array using the value of term as the key. The term variable must be prefixed with $ to indicate that the value of the variable should be used rather than the literal string term:

 [% term %]: [% terms.$term %]

The output generated for the complete block is as follows:

You know the following terms:
 frood: really, amazingly together guy
 hoopy: really together guy
 sass: know, be aware of, meet, have sex with

Conditionals

Conditionals are another powerful language feature that allow your templates to make decisions about what to process and what not to process, based on the values of variables and more complex expressions.

We saw an example of the IF directive in Example 1-3, shown here in condensed form for brevity:

[% IF order.destruction %]
   As you will no doubt be aware...
[% ELSE %]
   Our representatives will be...
[% END %]

If the order.destruction variable is true, the first block, between the IF and ELSE directives, is processed. Otherwise, the block between the ELSE and END is used.

The notion of truth is, in this sense, the same as it is for Perl. If the variable is defined and contains any kind of value except an empty string or the number zero, both Perl and the Template Toolkit will consider it to be true. If the variable is undefined, or contains a zero-length string or the number zero, it is false. This applies to all Template Toolkit directives that perform operations based on evaluating a variable or more complex expressions for truth.

Filters, Plugins, and Macros

There’s plenty more in the Template Toolkit that we introduce in the chapters that follow. The following examples give a taste of what is to come.

Filters allow you to postprocess the output of a block of template markup. The html filter, for example, will convert any HTML-sensitive characters, such as <, >, and &, into their equivalent HTML entities, &lt;, &gt;, and &amp;.

[% FILTER html %]
   Home > Dent > Friends > Slartibartfast
[% END %]

This generates the following output, which, when displayed as HTML on a web browser, will show the original > characters as intended:

Home &gt; Dent &gt; Friends &gt; Slartibartfast

See Chapter 5 for further details.

Plugins allow you to load and use Perl modules in templates without having to write a Perl wrapper program to do it for you. The following examples show how the CGI plugin (which delegates to Lincoln Stein’s CGI.pm module) can be used for CGI programming:

[% USE CGI %]
[% name   = CGI.param('name')   or 'Arthur Dent' %]
[% planet = CGI.param('planet') or 'Earth' %]
 Welcome [% name %] of planet [% planet %].

Plugins also have their own chapter, Chapter 6.

The final teaser that we’re going to show you is the MACRO directive. This allows you to provide simple names for more complex commands, as the following example shows:

[% MACRO header(title, author)
     IF name =  = 'Arthur Dent';
        INCLUDE arthur/header
          title = "Arthur Dent: $title";
     ELSE;
        INCLUDE guest/header
          title = "Guest User: $title";
     END;
%]

Don’t worry if you can’t make much sense of that now. The point that we’re illustrating is that sometimes Template Toolkit code can get quite complex. However, the MACRO directive allows you to define the complicated part in one place so that you can use a much simpler call to the macro in the rest of your templates:

[% header('My Home Page', 'Arthur Dent') %]

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.

So the golden rule of web programming is that there is no golden rule. There are golden tools, and we like to consider the Template Toolkit among them, but a tool is only as good as the person who uses it. In the next chapter, we look at using the Template Toolkit to generate web content so that you can become familiar with its ways and start crafting your own web sites.



[1] Which of course, we still rely on a great deal, not only as the language in which the Template Toolkit is written, but also as the means by which you can extend it and add your own custom functionality to your templates, as we will see in the next section.

Get Perl Template Toolkit now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.