Templates: Separating Programs from Design

Make web site design changes easier by using templates—HTML pages with embedded Perl code.
Templates

Luckily, we can create such hybrid Perl/HTML pages using the Text::Template Perl module, written by Mark-Jason Dominus. This module, available from CPAN at http://www.perl.com/CPAN/, allows us to take such hybrid files, evaluate the Perl parts, leave the pure HTML alone and send the results to the user's web browser. While the template module is identified as beta software and is not guaranteed to be stable, I have been using it for some time and have not encountered any problems. (I wish that I could say that about some of the commercial software that I use.) Although The template module is not designed to work exclusively with HTML pages, it is in this area that I have found it to be highly useful.

Templates are pages of HTML that contain zero or more pieces of Perl code. (Thus, a plain HTML file is also a template, although such files don't do anything special.) The Perl code is contained inside the curly braces that Perl uses to identify blocks within programs. For example, here is one template that displays the time of day as recorded on the server:

<HTML>
<Head>
<Title>Welcome to our site</Title>
</Head>
<Body>
<P>Welcome to our site!The time is now
{localtime;}
</>P
</Body>
</HTML>

At first glance, the above template appears to be HTML and nothing more. If you look within the curly braces ({ }), you will see Perl code hiding there. In this particular case, we have used the Perl function “localtime”, which prints out the time and date using the standard Unix format.

Because the above file looks and acts like HTML—it is HTML, after all, except for the Perl code—we can give it to our designers, who can change the layout in any way they might like. If they wish to insert an image before/after the time or if they wish to center the time of day, they can do so by using the familiar HTML tags. The site's programmers merely have to stress the importance of not modifying the text contained within the curly braces, which should be off-limits to them. By the same token, the site's programmers should only modify the code contained within the curly braces, since that is the portion for which they are responsible.

By using templates, we get the best of both worlds. Pages can contain programs, and thus, can modify their output depending on circumstances, while styling is still determined by the HTML surrounding the blocks of code.

Writing templates is admittedly something that takes a bit of time to grasp; however, the principles of writing templates are easy to understand. As mentioned above, anything within curly braces is considered to be Perl code and is replaced by the results of its evaluation. Thus, the expression:

{ 2 + 2; }

returns 4, and the expression:

{
        $browser = $ENV{"HTTP_USER_AGENT"};
        $outputstring = "<P>You are using \"$browser\"
as your browser.</P>\n";
}
returns a string telling the user which browser he is using, bracketed by HTML “paragraph” tags.

It is also possible to make calculations in one block of Perl and to use the results of those calculations in a later block. Thus, we can create the following:

<HTML>
<Head>
<Title>Welcome to our site</Title>
</Head>
{
$time = localtime;
$browser = $ENV{"HTTP_USER_AGENT"};
}
<Body>
<P>Welcome to our site! The time is now
{ $time; }
</P>
<P>You are using {$browser;} to view our site.</P>
</Body>
</HTML>

In this code, we use the first block of Perl to assign variables needed in the rest of the template. It might seem a bit contrived but can be of great help when creating large, complicated templates to set up a number of variables in the first block and then to refer to them in subsequent blocks.

If we are not careful when writing blocks of code, we can accidentally insert some extraneous characters into our resulting page of HTML. In the above example, the first block of code assigns values to variables. The code block itself returns the value of $browser, since that was the last variable assignment. In other words, our users see the name of their browser twice—once where the first block sits and the second, where we might expect to see it, in the third Perl block.

In order to avoid such problems, I generally use a variable named $outputstring, which is used solely for the purpose of sending output to the resulting page of HTML. At the beginning of each block, I assign $outputstring the empty string (""), ensuring that it is not tainted by values from previous blocks. The last line of each block is then set to $outputstring;, which evaluates to the value of $outputstring and is sent to the user's browser. In between these two uses of $outputstring I can perform any calculations that I want—and anything that I want to send to the user is simply concatenated onto the current value of $outputstring.

Since CGI variables are actually environment variables and child processes inherit environment variables from their parents, we can also access CGI variables from within our templates. We have already seen this in the above examples, when we retrieve $ENV{"HTTP_USER_AGENT"}, which should return the identifying string that web browsers send to web servers along with their document requests.

Because the code inside templates is full-blown Perl, we can use all of the techniques and code that we ordinarily use, including the use of library modules for databases, centralized libraries of code, and just about anything else available.

Of course, you need to be sure that your code is debugged before releasing it on an unsuspecting public. It is quite embarrassing to create a template and put it out in a public area of your web site, only to discover a bug that causes the entire template to crash. Actually, the template won't crash; the template module is smart enough to catch problems and point them out on the resulting page of HTML. Debugging templates can be tricky, so be sure to allocate additional testing and debugging time whenever you use templates rather than straight CGI programs.

______________________

White Paper
Linux Management with Red Hat Satellite: Measuring Business Impact and ROI

Linux has become a key foundation for supporting today's rapidly growing IT environments. Linux is being used to deploy business applications and databases, trading on its reputation as a low-cost operating environment. For many IT organizations, Linux is a mainstay for deploying Web servers and has evolved from handling basic file, print, and utility workloads to running mission-critical applications and databases, physically, virtually, and in the cloud. As Linux grows in importance in terms of value to the business, managing Linux environments to high standards of service quality — availability, security, and performance — becomes an essential requirement for business success.

Learn More

Sponsored by Red Hat

White Paper
Private PaaS for the Agile Enterprise

If you already use virtualized infrastructure, you are well on your way to leveraging the power of the cloud. Virtualization offers the promise of limitless resources, but how do you manage that scalability when your DevOps team doesn’t scale? In today’s hypercompetitive markets, fast results can make a difference between leading the pack vs. obsolescence. Organizations need more benefits from cloud computing than just raw resources. They need agility, flexibility, convenience, ROI, and control.

Stackato private Platform-as-a-Service technology from ActiveState extends your private cloud infrastructure by creating a private PaaS to provide on-demand availability, flexibility, control, and ultimately, faster time-to-market for your enterprise.

Learn More

Sponsored by ActiveState