In the previous segment of this
tutorial
, you learned the basics of the dTemplate engine, from how the
engine works to how
to use multiple templates on a single page
. In this second part, I’ll show
you a few more techniques to get the most out of dTemplate, including repeating
elements, using a function in place of a variable value, and linking the
dTemplate engine to a MySQL database for data-driven templating.

Using built-in Perl functions in a template

Let’s begin with something simple: using the return value of
a function in the call to
parse(). The examples in the previous article involved
replacing template variables with hard-coded values. However, it’s quite likely
that you’ll sometimes need to replace a template variable with a value
generated from a calculation or function. This simple template illustrates one
example:

<!– now.tmpl –>
<html><head></head>
<body>

It is now $NOW$

</body></html>

In this template, the variable $NOW$ must store the current
date and time, so its value cannot be hard-coded into a script. Therefore, we
must assign a value to this variable from a function that dynamically generates
the current time, as in Listing A.

The parse() function will replace the variable $NOW$ with
the return value of the function. This is an important capability, as you’ll
see shortly.

Using custom functions in a template

Just as you can use Perl’s built-in functions to assign
values to template variables, so also can you define your own. In order to
illustrate, consider the following template:

<form>Select from the following options:
<select>
$OPTIONS$
</select>
</form>

Now, I need to generate a series of <option> boxes to
replace the $OPTIONS$ variable. Assuming I have the option list available in a
Perl array, it’s possible to write a simple Perl function that generates this
option list through a loop and assigns the list to the $OPTIONS$ variable, as
in Listing B.

In this case, the value assigned to the $OPTIONS$ variable
is actually a user-defined Perl subroutine. This subroutine reads the contents
of the @countries array and generates a series of <option> elements,
which are then returned to the enclosing code block. The parse() function interpolates
this returned value with the $OPTIONS$ placeholder to create the result shown in
Listing C.

Repeating elements

Another way to do the same thing is to split the template
into two pieces—one for the main form and one for the element that repeats.
This is a somewhat more elegant alternative to the example on the previous
page. Consider the following two templates, form.tmpl:

<!– form.tmpl –>
<form>
Select from the following options:
<select>$OPTIONS$</select>
</form>

and option.tmpl:

<!– option.tmpl –>
<option>$ITEM$</option>

In this case, I first need to generate the option list from
the option.tmpl template by repeatedly calling parse() on it and appending the
output from each run to the previous runs. You’ve already seen this technique
in the first part of
this article
. Once the option list is generated, it’s a simple matter to
parse the outer template and assign the option list to the $OPTIONS$ variable,
as in Listing D.

Example application:
Using dTemplate with MySQL

Now, how about putting everything you’ve learned into
practice. This next example shows you how to hook your dTemplate system up to a
MySQL database for dynamic page generation. Here I’ll assume the existence of a
MySQL table containing user information, as in Listing E.

My script must generate two pages, both driven off this
table. The first page is an index of user names generated when the script is
called without any arguments. The second is a page containing details on a
specific user, and it requires the user name to be provided to the script.

Both pages can be generated from the same script simply by
keying on the presence or absence of a user name in the script input. The first
step is to generate the templates for the two pages. First, the index page, index.tmpl:

<!– index.tmpl –>
<html><head></head>
<body>

Available users:

<ul>$LIST$</ul>

</body></html>

And for an individual list item, li.tmpl:

<!– li.tmpl –>
<li><a href=”/cgi-bin/script.cgi?username=$NAME$”>$NAME$</li>

And here’s the template for the user details page, detail.tmpl:

<!– detail.tmpl –>
<html><head></head>
<body>

User information for <i>$USER$</i>:
<p>
<table border=”1″ cellspacing=”0″ cellpadding=”5″> <tr>
<td>First name</td>
<td>Last name</td>
<td>Date of birth</td>
<td>Nationality</td>
<td>Age</td>
</tr>
<tr>
<td>$FNAME$</td>
<td>$LNAME$</td>
<td>$DOB$</td>
<td>$NAT$</td>
<td>$AGE$</td>
</tr>
</table>

</body></html>

The script that does all the work is in Listing F. It combines
two of Perl’s most powerful modules, CGI.pm and DBI.pm, with the dTemplate
module.

First, a set of template objects is created, one for each
template, and a connection is opened to MySQL in preparation for subsequent
queries. Then, depending on whether the script is sent a user name, a query is
generated to either obtain a list of users or the record for a specific user.
The values returned by the query are then inserted into the template.

Figure A is a screenshot of what the final index page should look like, and Figure B is the detail page:

Figure A

Index page generated by Listing F

Figure B

Detail page generated by Listing F

Notice that the user list in the index page is generated
incrementally using the technique demonstrated previously, while each user’s
age is calculated from the date of birth within the query itself using MySQL’s YEAR()
function.

I hope the numerous examples and techniques presented in
this article give you some insight into how a template system works and
encourage you to try it for yourself. As you uncover interesting tips or tricks
of your own, come back here and share them on the discussion page for this
article.