Using templates with Perl/CGI

Monday Dec 14th 1998 by Dave Edis

Most Web applications by nature use a lot of HTML. Think about a Web-based email program such as Hotmail. HTML is used to display numerous pages including the login screen, mailbox, read message, send message, folders, menubar, setup options, and many other pages.

Most Web applications by nature use a lot of HTML. Think about a Web-based email program such as Hotmail. HTML is used to display numerous pages including the login screen, mailbox, read message, send message, folders, menubar, setup options, and many other pages.

The problem with having HTML in Web programs is that there's just so much of it. Every single screen in your program needs an HTML page. And where does all that HTML usually go? In your Perl source code. This can add literally thousands of lines of code making it difficult to scan and troubleshoot your programs, difficult to see each individual screen without cutting and pasting it into its own file, and even more difficult to edit those HTML screens, let alone have some one else edit them. The solution? Put that HTML where it belongs, in ".HTML" files! And write your Perl/CGI programs to make use make use of these files as HTML Templates.

Finding a new home for all that HTML

The best way to organize your HTML Templates is to put them near your program (either in the same directory or a sub directory named "/templates/") and to give them a good descriptive name. I usually make the first character of the filename an underscore followed by the program name and the program section. I use the underscore at the beginning to differentiate between regular HTML files and HTML templates.

For example, pretend we were to create a Web-based email program called "Web Mail", our templates may be named as follows:

_webmail_login.html                  # login 
_webmail_message_list.html           # list messages 
_webmail_message_read.html           # read message 
_webmail_message_send.html           # create/send message 
_webmail_message_erase.html          # erase message
_webmail_message_erase_confirm.html  # confirm erase 
_webmail_logoff.html                 # logoff  

This makes it easy to see at a glance what the file is for and even easier to come back later and make any changes or see what a specific page looks like. Also, if you work with other web developers and designers, they can make changes without fear or messing up your program by accident or remembering to backslash all the @ symbols.

Displaying templates in Perl/CGI

Before we can start moving all that HTML out of our Perl/CGI programs and into HTML template files we need some way to display them. So, we're going to create a Perl subroutine called
. Here's the code:

sub Template { 
local(*FILE);         # filehandle 
local($file);         # file path 
local($HTML);         # HTML data 

$file = $_[0] || die "Template : No template file specified\n"; 

open(FILE, "<$file") || die "Template : Couldn't open $file : $!\n";
while () { $HTML .= $_; }

$HTML =~ s/\$(\w+)/${$1}/g; 

return $HTML; 

Most of this is pretty basic, we're just opening a template file, reading the contents and passing it back to the program. The trick is the following regular expression that searches for Perl variables in your HTML template (i.e., "$date") and substitutes them with the value of the that variable as defined in your program:

$HTML =~ s/\$(\w+)/${$1}/g;

Here's how it works. The regexp searches for variable names that starts with a "$" followed by one or more "word characters." In the regexp, "\w" means a "word character" (a-z,A-Z,0-9 or an underscore) and "+" means one or more times. The brackets around "\w+" tell it to remember what variable name was that was matched and save it in "$1." And finally, "${$1}" is evaluated to find the value of that variable. Remember, the name of the variable is stored in $1. And here's how you use it in your program.

### Display Login Screen 
print "Content-type: text/html\n\n"; 
print &Template("_webmail_login.html");  

So now, even though your HTML is stored in templates files outside of your program, variables will be translated just like they would in Perl.

Complex Templates and HTML Fragments

Now, there some situations where just using a single template won't work such as a search engine where you need to return a different number of results based on what was found, or a weather page where you may want to display different images and text based on the forecast. In cases like these you can use multiple template files to make up the screen. For example, you can divide the search engine results page up into sections:

_search_results_header.htmlf       # page header 
_search_results_result.htmlf       # result row 
_search_results_footer.htmlf       # page footer  

These sections are sometimes called HTML fragments because it's really just a fragment of a full HTML page. Giving the HTML fragments a different file extension ".htmlf" helps to distinguish them from full HTML files. By breaking your HTML page up into fragments you can have your program print as many search results as are required.

print &Template("_search_results_header.htmlf"); 
foreach $result (@results) { 
    print &Template("_search_results_result.htmlf"); 
print &Template("_search_results_footer.htmlf");  

For our weather page example you can use HTML Fragments as well, but instead of printing them one after another you can load the HTML fragments that are required and display them inside of another page. Say we have our main weather page template _weather.html and where we want to insert the three day forecast we enter the variables "$day1 $day2 $day3." Now we'll create a small HTML fragment file for each possible weather condition and then load them as needed:

### Load HTML fragments for weather forecast 
$day1 = &Template("_weather_sunny.htmlf"); 
$day2 = &Template("_weather_cloudy.htmlf"); 
$day3 = &Template("_weather_snowing.htmlf"); 

print &Template("_weather.html");  

Where to go from here

One of the things that may take some getting used for designers is having all those funny looking variables in the HTML files (i.e., "Today is $date"). Some people find it easier to use another symbol (or format) other than a preceding "$" to identify variables. With a few modifications you can easily have your program use "%variable%" or "__variable__" or some other variant if that makes more sense to you.

Even if this is the first time you've thought about using templates instead of in-line HTML in your programs, I think you'll find it's easy and fast to switch over and that templates make a lot of sense.

Dave Edis is president of Edis Digital, a new media solutions firm in Vancouver, Canada. Edis Digital develops Web-based publishing tools and applications for companies around the world.

Mobile Site | Full Site
Copyright 2017 © QuinStreet Inc. All Rights Reserved