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.

______________________

Webinar
One Click, Universal Protection: Implementing Centralized Security Policies on Linux Systems

As Linux continues to play an ever increasing role in corporate data centers and institutions, ensuring the integrity and protection of these systems must be a priority. With 60% of the world's websites and an increasing share of organization's mission-critical workloads running on Linux, failing to stop malware and other advanced threats on Linux can increasingly impact an organization's reputation and bottom line.

Learn More

Sponsored by Bit9

Webinar
Linux Backup and Recovery Webinar

Most companies incorporate backup procedures for critical data, which can be restored quickly if a loss occurs. However, fewer companies are prepared for catastrophic system failures, in which they lose all data, the entire operating system, applications, settings, patches and more, reducing their system(s) to “bare metal.” After all, before data can be restored to a system, there must be a system to restore it to.

In this one hour webinar, learn how to enhance your existing backup strategies for better disaster recovery preparedness using Storix System Backup Administrator (SBAdmin), a highly flexible bare-metal recovery solution for UNIX and Linux systems.

Learn More

Sponsored by Storix