Scripting languages such as PHP and Perl make it very easy to
create dynamic Web pages by placing program code inside HTML markup. This code
does the dirty work—connecting to a database, processing user input, performing
calculations—and produces output which then integrates neatly with the rest of
the page. The only problem: Your code ends up looking like a bowl of spaghetti,
because the HTML markup and scripting functions are so closely intertwined with
each other.

It’s precisely this reason that causes many developers to
look for more efficient ways of structuring their dynamic Web pages. In this
more efficient world, HTML markup or layout code is separated from the business
logic or functions that drive the page. This means that Web designers can work
on “how a page looks” independent of Web developers, who only need to
focus on “how the page works.” For content-heavy sites that receive
data from a variety of sources—XML, RDF, RSS, MySQL—a further degree of
separation can be introduced through a content layer, which takes care of
“what the page contains.”

In this article, I’ll introduce you to this more
efficient way of structuring Web pages with dTemplate, a Perl-based template
engine. You’ll learn the basics, starting with how to separate page layout from
business logic, and ending with how to integrate multiple templates to generate
a single page.

How a template engine works

An important component of the tiered approach to Web
development is a “template engine,” which allows a designer to create
page templates for the user interface. These templates typically contain no
data at all; instead, they contain placeholders for data, which are
automatically replaced with content at run-time by the template engine. The retrieval
of the content from one or more data sources, as well as any specific scripting
functionality required by the page, is created independently from the layout
template.

The template engine thus takes care of integrating the
layout with the business logic and presenting a composite result when the page
is requested by a user. This separation between layout and content makes it
possible for designers and developers to work on the same page simultaneously,
without interfering with or overlapping each other’s scope of responsibility.

A number of template engines exist for both PHP and Perl.
The one I’m using for this tutorial is called dTemplate,
and it’s fast, stable, and fairly full-featured (three important attributes you
should always look for in a template system).

dTemplate is licensed under the GPL and is maintained by
Balázs Szabó. It is written in Perl with a C extension and can be downloaded from
CPAN
. Detailed installation instructions are provided in the download
archive, but the simplest way to install it is to use the CPAN shell, as
follows:

shell> perl -MCPAN -e shell
cpan> install dTemplate

If you use the CPAN shell, dependencies will be
automatically downloaded for you (unless you told the shell not to download
dependent modules). If you choose to manually download and install dTemplate,
the installation procedure is the standard make-install routine, as follows
(this tutorial uses version 2.4 of dTemplate):

shell> tar -xzvf dTemplate-2.4.tar.gz
shell> cd dTemplate-2.4
shell> perl Makefile.PL
shell> make
shell> make install

Creating a simple template

Once you have dTemplate installed and configured, begin by
creating a subdirectory under your Web server document root called templates/ and placing the file color.tmpl inside it. Here is what goes
inside color.tmpl:

<html><head></head>
<body>

<h2>My favorite color is $FAVCOLOR$</h2>

</body>
</html>

This is fundamentally what every template looks like—a
regular HTML page that contains layout code but no actual data. The data is
represented by one or more template variables, which are enclosed in $ symbols.
In the example above, $FAVCOLOR$ is a template variable that will be replaced
with an actual value by the template engine.

So now let’s look at the script that will
utilize this template
.

Parsing a template and replacing template variables

The simple template we created
earlier
is only half the puzzle. The other half is a CGI script in Listing A called color.cgi, which must be placed inside your server’s CGI-BIN
directory.

This script takes care of reading the template file into the
dTemplate engine and replacing the variable placeholder inside it with an
actual value. There are three basic steps:

  1. The
    new() method accepts a hash whose “file” key points to the
    template file and creates a $tmpl object to represent the template.
  2. The
    parse() method of our newly-minted $tmpl object accepts a hash of
    key-value pairs (where the keys correspond to the template placeholders,
    and the values represent the content that will replace them) and performs
    variable interpolation on the template by replacing the $FAVCOLOR$
    placeholder with the value “indigo”.
  3. The
    return value of parse() is stored in the $output variable and printed to
    the browser after the mandatory “Content-Type” header.

Listing B shows what
users will see when they navigate to http://server/cgi-bin/color.cgi.

Again, any dTemplate requires at least two components: a
Perl script with the business logic and one or more template files containing
the layout.

The advantages of separating layout and code

Splitting a Web page in this manner has two important
advantages. First, it physically separates the HTML layout from server-side
code, allowing developers to work on their portion of a page independently from
the designers. This separation means a designer can also update the way a page
looks without touching the server-side code. Yes, the designer does need to
reuse the correct variable placeholders in their new locations. But it’s much
easier to relocate simple variable placeholders than to navigate complex Perl or
PHP code blocks looking for the snippets of HTML buried within.

Second, because the page template is stored in a separate
file, the same template may be called from different scripts. This makes it
possible to easily reuse components of the user interface—menus, buttons,
tables, headers and footers—potentially reducing repetition and redundancies.

Using multiple templates in a single page

Using a template engine gives you the ability to abstract
common page elements into separate files and import them into your pages when
needed (and with different data each time, if that’s what you want). To do this,
you must first break up your Web page into separate files or
“mini-templates,” and then create dTemplate objects for each template.
You can then parse() each template, perform variable interpolation as needed,
and append the result of each parse() run to previously generated output to
create a composite page.

It’s easier in practice than it sounds. To illustrate, let’s
assume you have a page containing three sections: the header, footer, and body.
Break up these sections into three separate template files called header.tmpl (Listing C), body.tmpl (Listing D), and footer.tmpl (Listing E).

Now, what you need is a script to read and parse each
template, and generate a single page using all three of them. See Listing F for an example.

Since this script has to deal with three templates, and thus
three dTemplate objects to be created and referenced, I’ve used a slightly
different technique. I’ve first created a Perl hash to store the names of the
template files, as well as a convenient short name for each, and then used a
loop to create dTemplate objects for each file. These dTemplate objects are
accessible using the syntax $template->{shortname}, which makes it easy to
access individual methods of each.

Once the dTemplate objects are created, it’s a simple matter
to parse() each one and replace the variables inside it with actual content.
The output of each parse() run is appended to the output of the previous run,
thereby incrementally building the Web page. The end result will look something
like Figure A.

Figure A

Output assembled from three HTML templates and one logic template

The cool part? You can use the same header and footer
template across your entire Web site just by importing it as needed. Heck, you
can even customize the header and footer on a per-page basis by using template
variables for the volatile data and replacing them with different values in each
script (see the $TITLE$ variable in Listing C as an illustration).

The best part? Whenever you want to change the page header
or footer for your entire site, your designer only needs to edit a single HTML file!

That’s it for now. Look for future articles coming soon,
where I’ll show you how to use a single template for repeated elements such as table rows or lists, use the result of a function in a template variable, and
hook dTemplate up to MySQL for truly dynamic page generation. Make sure you
come back for that!