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.
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.
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.
[% 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.
# 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.
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.
#!/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.
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.
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.
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.
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.
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,
<
, >
, and &
.
[% 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 > Dent > Friends > 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.