Introducing HTML::Template

Dan Horne
Dan Horne

The Comprehensive Perl Archive Network (CPAN) contains a vast array of modules that make a developer’s life much easier. You would do well to browse the treasures at before embarking on any new project.

As an example, in this tutorial I’ll provide a brief overview of how to install the HTML::Template module. But first, let’s see how you can install a Perl module on your system.

Installing Perl

Perl Installation on Windows

Perl for Windows is available as a free download at Installing a module is surprisingly simple; however, it does require that the module is in ActiveState’s ppd format.

Installation can be performed from the ppm shell:

PPM - Programmer's Package Manager version 3.1.
Copyright (c) 2001 ActiveState SRL. All Rights Reserved.

Entering interactive shell. Using Term::ReadLine::Stub as readline library.

Type 'help' to get started.

ppm> install HTML-Template

It’s as simple as that. If any dependencies exist, they will be installed first. Note that not all Perl modules have been packaged for ppm. To find out if a module is available, type search <module> in the shell.

If you require a module that’s not in ActiveState’s repository, it’s possible that someone else has packaged it. You can find a list of additional repositories by installing the PPM::Repositories module, then running this code:

use PPM::Repositories; 

for my $rep ( keys %Repositories ) {
   next unless $Repositories{$rep}->{Active};
   next unless grep { $_ == 5.8 } @{ $Repositories{$rep}->{PerlV} };
   print $rep, $/, $Repositories{$rep}->{location}, $/,
     $Repositories{$rep}->{Notes}, $/, $/;

Failing all else, you could install the module by hand. We discuss how to do this in the Unix/Linux section below.

Perl Installation on Unix/Linux

Perl installation on Unix and Linux can be achieved in two ways: manually, or automatically.

The Manual Way

Download the module, unzip and untar it.

$ tar zxvf HTML-Template-xx.tar.gz 
$ cd HTML-Template-x.x
$ perl Makefile.PL
$ make
$ make test
$ make install

If you wish to install the file manually under Windows, you’ll need to download nmake.exe from Microsoft. Then, simply replace make with nmake in the instructions above.

While the majority of modules are pure Perl, some may contain C code, in which case you will need a C compiler. (A compiler is never required for ppm packages).

Make sure that you peruse the README file before you install a module.

The Automatic Way

Some modules are dependent on other modules, which in turn may have other dependencies. Installing all these modules can be a bit tedious, but there is an alternative: install the CPAN package. Then, simply invoke the cpan shell from the command line:

$ cpan

The first time cpan is run, it will configure itself. Answer the prompts, and when the configuration is complete, you can install your package:

cpan> install HTML::Template

If any dependencies exist, cpan can fetch and install them.

Now that you know how to install Perl modules, let’s take a closer look at one of Perl’s templating solutions: HTML::Template.

Introducing HTML::Template

Perl is great as a prototyping language because it’s very expressive: developers can do a lot in a few lines. A corollary of this is that it’s easy for a small application to morph into something much bigger than anticipated. Maintaining and extending such an application can become quite onerous.

Writing large Web applications using traditional CGI techniques is an approach that doesn’t scale very well. If you’re the only developer, mixing your HTML with your Perl may be tolerable, but this approach doesn’t work when you’re part of a team. Your typical Web designer won’t want to start changing your Perl code if the design needs to be changed.

Most Web languages provide some means to separate the application code from the markup code. In most cases, the HTML is placed in separate template files, which then act as containers for dynamic data. With languages like PHP, the templates can be thought of as an extension of the core language itself, although, if you’re like me, you’ll still prefer third-party template solutions like Smarty.

Perl has a number of templating solutions. HTML::Mason and the Template Toolkit are two of the most popular solutions, and offer powerful capabilities. Developers can place sophisticated logic in their templates, but unless they’re disciplined, they can undo many of the benefits of using templates in the first place, including the separation of the business logic from the interface.

HTML::Template is a lightweight alternative. It aims to provide the most basic functionality for creating Web pages, and no more. The philosophy is to keep your Perl and your HTML separate.

A Simple Example

Below is an example of a simple template, template1.tmpl. Note that it consists mainly of standard HTML with a single non-standard tag, tmpl_var, where the attribute name is set to day.

 <title>Template 1</title>
Today is <tmpl_var name=day>

Using the template template from Perl is very simple:

1.  #!c:/perl/bin/perl -T 
2.  use CGI qw(:all);
3.  use HTML::Template;
4.  use POSIX;
5.  print header;
6.  my $template = HTML::Template->new(filename => 'template1.tmpl');
7.  $template->param(day => strftime('%A', localtime()) );
8.  print $template->output();

Line 1 simply states where the Perl interpreter is located. The -T switch means we’re in taint mode. This provides an extra level of security to Web applications by telling Perl that we should not trust any user input unless we explicitly state otherwise. This is good practice: you should always include this switch as a matter of course.

Line 2 imports the module. This isn’t 100% necessary: we could write out own CGI functions by hand, but this risks introducing all sorts of bugs and security issues. The CGI module is very well-tested, and you should always use it when writing CGI applications.

At line 3, we import the HTML::Template module. Line 4 brings in the standard /POSIX functionality. This allows us easily to determine the day of the week later on. Keep in mind Perl’s philosophy of There’s More Than One Way to do It (TMTOWTDI) — we could have done this using any number of date modules.

Line 5 is CGI shorthand for print "Content-Type: text/htmlnn". We need to return the content type before we output the rest of the Web page. On line 6, we create the template object. The file name of our template is supplied as the only parameter.

Line 7 sets the <tmpl_var> tag with the name of "day" to the day of the week. If you’re not familiar with the POSIX strftime function, %A is shorthand for returning the day of the week. The same formatting masks are available to PHP and C.

And finally, at line 8, we display the Web page.

So now we’ve been introduced to the basic HTML::Template philosophy: we create mostly HTML code, and we intersperse some <tmpl> placeholders for dynamic content. The syntax is kept deliberately simple; your Web designers can simply maintain the site’s look and feel through standard HTML and a small number of additional tags.


Although the <tmpl_var> tag is extremely useful, it isn’t sufficient by itself. Often, we’ll need to present a set of data in a tabular format. This is where the <tmpl_loop> tag comes in:

<title>Template 2</title>  
 <tmpl_loop name="language">  
   <td><tmpl_var name="language_name"></td>  
   <td><tmpl_var name="description"></td>  

Essentially, we have a loop called language, and we have two variables inside it, called language_name and description. On the Perl side of things, HTML::Template expects loops to be passed as an array reference of hash (associative array) references:

1.  #!c:/perl/bin/perl -T  
2.  use CGI qw(:all);  
3.  use HTML::Template;  
4.  my @languages = (  
5.      {  
6.          language_name => 'Perl',  
7.          description   => 'Practical Extraction and Report Language'  
8.      },  
9.      {  
10.          language_name => 'PHP',  
11.          description   => 'Hypertext Preprocessor'  
12.      },  
13.      {  
14.          language_name => 'ASP',  
15.          description   => 'Active Server Pages'  
16.      },  
17.  );  
18.  print header;  
19.  my $template = HTML::Template->new( filename => 'template2.tmpl' );  
20.  $template->param( language => @languages );  
21.  print $template->output();

Lines 4-17 define the array of hash references. The hash key names must be the same as the template <tmpl_var> names inside <tmpl_loop>. At line 20, a reference to the languages array is passed to the template tag <tmpl_loop name=language>.

Setting the loop data in our Perl script by hand is simple enough, but in the real world, we’re likely to retrieve our template data from a database. Let’s say we have a table called "languages", with a column called "language_name" and another called "description." We can just as easily generate the output from a query:

1.  #!c:/perl/bin/perl -T  
2.  use CGI qw(:all);  
3.  use HTML::Template;  
4.  use DBI;  
5.  my $dbh = DBI->connect('dbi:<driver>:<my db>', '<user>', '<password>');  
6.  my $sql = "select * from languages";  
7.  my $sth = $dbh->prepare($sql);  
8.  $sth->execute();  
9.  my $languages = $sth->fetchall_arrayref({  
10.     language_name => 1,  
11.     description   => 1}  
12.  );  
13.  print header;  
14.  my $template = HTML::Template->new( filename => 'template2.tmpl' );  
15.  $template->param( language => $languages );  
16.  print $template->output();

At line 4, we bring in the DBI, Perl’s database module. Line 5 connects to the MySQL database. Replace <driver>, <my db>, <user> and <password> with whatever is appropriate for your system. This isn’t production code — we wouldn’t normally hard-code this information, and we would typically include checks to see if any of our database interactions failed.

Lines 6-8 prepare our SQL select statement and execute it. In lines 9-12 we fetch the entire result set. DBI offers many different formats for the data. An array reference is best for us, because this is the format that HTML::Template expects. We can specify in a hash reference the columns that we wish to name in our array.


Finally, we may wish to alter the output based on certain conditions. HTML::Template offers both an IF and an UNLESS tag. Suppose, for example, that we want to present a special message if no languages are found:

<title>Template 3</title>  
   <tmpl_if name=language>  
 <tmpl_loop name="language">  
   <td><tmpl_var name="language_name"></td>  
   <td><tmpl_var name="description"></td>  
 Sorry, no languages were found  

All that we’ve done here is wrap our loop in a conditional. If the language parameter is true, the results are displayed; otherwise, we’ll let the person viewing the page know that no records were found.

UNLESS is similar to IF, except that instead of checking if a condition is true, we're seeing if it isn't (i.e. "unless true, do this").

Multiple Templates Per Page

Unless your page is trivial, you'll most likely want to add headers, footers and even some form of navigation. You can include other templates quite easily:

<tmpl_include name="menu.tmpl">
Is that It?

We’ve covered the basics of HTML::Template here. Sam Tregar, its author, was very careful not to include any bells and whistles that might undermine the philosophy of keeping the business logic separate from the user interface. Despite the limited template syntax, I’ve never had a requirement for anything more sophisticated. However, against Sam’s better judgment, he created an extension called HTML::Template::Expr, which allows a developer to add expression and function support.

Lastly, for the PHP and Python programmers out there, HTML::Template has been ported to your language of choice. More information can be found at

Frequently Asked Questions about HTML Templates

What are the benefits of using HTML templates?

HTML templates offer a variety of benefits. They provide a pre-designed structure that can save you a lot of time and effort. Instead of starting from scratch, you can use the template as a starting point and customize it to suit your needs. HTML templates are also reusable, which means you can use the same template for multiple web pages. This can help maintain consistency across your website. Additionally, HTML templates are easy to use and require no special software to edit. All you need is a basic text editor.

Can I customize HTML templates?

Yes, HTML templates are fully customizable. You can change the colors, fonts, images, and other elements to match your brand identity. You can also add or remove sections as needed. To customize an HTML template, you need to have a basic understanding of HTML and CSS. However, there are many online resources available that can help you learn these skills.

Are HTML templates responsive?

Most modern HTML templates are designed to be responsive. This means they automatically adjust to fit different screen sizes, from desktop monitors to mobile phones. This is important because it ensures that your website looks good and functions properly on all devices. When choosing an HTML template, make sure it is labeled as responsive.

How do I implement an HTML template?

To implement an HTML template, you first need to download the template files to your computer. These files usually include an HTML file, a CSS file, and possibly some JavaScript files. Once you have the files, you can open them in a text editor and start customizing the template. When you’re done, you can upload the files to your web server.

Can I use HTML templates for email marketing?

Yes, HTML templates can be used for email marketing. They can help you create professional-looking emails that are consistent with your brand. However, designing emails is a bit different from designing web pages. You need to consider factors like email client compatibility and the use of tables for layout. Some HTML templates are specifically designed for emails and take these factors into account.

Are there free HTML templates available?

Yes, there are many free HTML templates available online. These templates can be a great resource if you’re just starting out or if you’re on a tight budget. However, keep in mind that free templates may not offer as many features or as much support as paid templates.

What is the difference between an HTML template and a WordPress theme?

An HTML template is a pre-designed webpage that you can customize and use to build your website. A WordPress theme, on the other hand, is a collection of templates and stylesheets that define the appearance and display of a WordPress-powered website. While HTML templates require some coding knowledge to use, WordPress themes can be installed and customized directly from the WordPress dashboard.

Can I use HTML templates with a CMS like WordPress or Joomla?

While it’s technically possible to use an HTML template with a CMS like WordPress or Joomla, it’s not the most straightforward process. These systems are designed to work with their own specific themes and templates. If you want to use an HTML template, you would need to convert it into a theme or template for that CMS, which requires a good understanding of PHP and the CMS’s architecture.

How do I choose the right HTML template?

When choosing an HTML template, consider factors like the design, the features, the responsiveness, and the ease of customization. You should also consider the reputation of the template’s creator and the reviews from other users. Make sure the template fits your brand and your needs.

Can I sell my own HTML templates?

Yes, if you’re a web designer or developer, you can create and sell your own HTML templates. There are many online marketplaces where you can sell your templates. However, keep in mind that creating a high-quality template requires a good understanding of web design and coding. You also need to provide support to your customers.