Templates: Separating Programs from Design
So, how do we turn a hybrid Perl/HTML template into plain HTML to be sent to the user's browser? If users were shown these templates without some sort of translation, they would appear as HTML files with the Perl reproduced verbatim on the user's screen. This display is obviously not desirable.
The key is to have a CGI program, called wrapper.pl, to take the name of a template in its query string (i.e., the argument that a CGI program receives following the question mark in the URL). Once it has received the template name, wrapper.pl creates an instance of Text::Template and instructs that module to perform the magic necessary to turn our template into a page of HTML.We can then send the resulting HTML to our user's browser. As far as the user is concerned, the page was and is HTML; he does not know that we have used a template to create our output.
Here is a simple version of wrapper.pl:
#!/usr/bin/perl -
use strict;
use diagnostics;
use CGI;
use Text::Template;
# Create an instance of CGI
my $query = new CGI;
# Send an appropriate MIME header
print $query-header("text/html");
# Get the name of the template
my $file = "/home/httpd/html/templates/" . $query-param("keywords");
# Create an instance of template
my $template = new Text::Template(-type => FILE,
-source => $file);
# Perform the evaluation, and send the results
# to the user's browser
print $template-fill_in;
This program may appear quite simple, but we have hidden a great deal of depth within our calls to Text::Template—first when we open the file and when we ask the Template object to evaluate each of the small Perl programs inside the indicated template, it does so. Finally, we take the results of that evaluation and send them to the user's browser with the print statement.
Assuming the directory in which templates are stored not only makes the resulting URLs shorter but also makes your site somewhat more secure, since outsiders will not know your file system. It is also a good idea to remove any references to the parent directory (represented with “..”) in the filename passed to wrapper.pl, so as to avoid turning our program into a convenient way of looking at all of the files on the server's hard disk. One easy way to do this is to replace the original assignment of $file with the following two lines:
# Get the name of the template
my $file = "/home/httpd/html/templates/" . $query->param("keywords");
# Remove possible security problems
$file =~ s|/\.\./|/|g;
This will remove attempts to ascend one or more directories, making it more difficult for someone to spy on the contents of our server.
Thus, if we have a template named /home/httpd/html/templates/test.tmpl and a site called www.oursite.com, we can view the template in translated form by using the URL http://www.oursite.com/cgi-bin/wrapper.pl?test.tmpl. If we have another template in the same directory named foo.html, we can view it using the URL http://www.oursite.com/cgi-bin/wrapper.pl?foo.html.
One odd note that you should remember when creating templates is the fact that they are effectively served out of the CGI directory on your server (usually called cgi-bin). In all of the above templates, this does not make any difference. If our templates were to incorporate images whose URLs were named relatively (i.e., without a leading slash) rather than absolutely (i.e., with a leading slash), this could cause a problem.
For example, it is quite common for HTML files to be placed in one directory, while the images used by those files are placed in a subdirectory, perhaps named “images”. In order to create an HTML file with an image inside of it, we could do the following:
<HTML> <Head> <Title>Example of image</Title> </Head> <Body> <P>This is a sample Web page, containing an image.</P> <img src="images/graphic.gif"> </Body> </HTML>
But if we were to take this same file and feed it through wrapper.pl, the image would no longer appear. That's because the “image” subdirectory exists relative to the directory in which the HTML file resides, rather than the directory in which the CGI program resides.
One quick solution to this problem is to use the <base> HTML tag, with a URL other than the one under which it was invoked. The <base> tag looks like:
<base href="http://www.oursite.com/text/english/">
With this tag in place, our browser will know to load the image in the above template from http://www.oursite.com/text/english/images, regardless of whether the document was loaded from within the CGI directory or the original HTML directory. The problem with this approach is that it makes it more difficult to move files and directories to other places on the site—a trade-off that is often worth making.
One word of warning before I conclude. Normally, access to the CGI directory and to the programs contained within it is restricted to a small set of programmers who can be trusted to write and modify code on your system. With templates, that group is suddenly expanded to include all of the site's designers, who could theoretically modify the code within a template to perform malicious acts. Remember that since templates include code, it is a good idea to restrict access to the directory containing the templates, rather than granting it to everyone on your system.
In short, templates are a useful way to separate the design of a web site from the CGI programs it contains. By using them wisely, you will give everyone more freedom to do what they enjoy, as well as what they do best.
Reuven M. Lerner is an Internet and Web consultant living in Haifa, Israel, who has been using the Web since early 1993. In his spare time, he cooks, reads and volunteers with educational projects in his community. You can reach him at reuven@netvision.net.il.
Realizing the promise of Apache® Hadoop® requires the effective deployment of compute, memory, storage and networking to achieve optimal results. With its flexibility and multitude of options, it is easy to over or under provision the server infrastructure, resulting in poor performance and high TCO. Join us for an in depth, technical discussion with industry experts from leading Hadoop and server companies who will provide insights into the key considerations for designing and deploying an optimal Hadoop cluster.
Sponsored by AMD
Built-in forensics, incident response, and security with Red Hat Enterprise Linux 6
Every security policy provides guidance and requirements for ensuring adequate protection of information and data, as well as high-level technical and administrative security requirements for a system in a given environment. Traditionally, providing security for a system focuses on the confidentiality of the information on it. However, protecting the data integrity and system and data availability is just as important. For example, when processing United States intelligence information, there are three attributes that require protection: confidentiality, integrity, and availability.
Learn more about catching the bad guy in this free white paper.
Sponsored by DLT Solutions
| Designing Electronics with Linux | May 22, 2013 |
| Dynamic DNS—an Object Lesson in Problem Solving | May 21, 2013 |
| Using Salt Stack and Vagrant for Drupal Development | May 20, 2013 |
| Making Linux and Android Get Along (It's Not as Hard as It Sounds) | May 16, 2013 |
| Drupal Is a Framework: Why Everyone Needs to Understand This | May 15, 2013 |
| Home, My Backup Data Center | May 13, 2013 |
- RSS Feeds
- Dynamic DNS—an Object Lesson in Problem Solving
- Making Linux and Android Get Along (It's Not as Hard as It Sounds)
- Designing Electronics with Linux
- Using Salt Stack and Vagrant for Drupal Development
- New Products
- A Topic for Discussion - Open Source Feature-Richness?
- Drupal Is a Framework: Why Everyone Needs to Understand This
- Validate an E-Mail Address with PHP, the Right Way
- What's the tweeting protocol?
Enter to Win an Adafruit Pi Cobbler Breakout Kit for Raspberry Pi

It's Raspberry Pi month at Linux Journal. Each week in May, Adafruit will be giving away a Pi-related prize to a lucky, randomly drawn LJ reader. Winners will be announced weekly.
Fill out the fields below to enter to win this week's prize-- a Pi Cobbler Breakout Kit for Raspberry Pi.
Congratulations to our winners so far:
- 5-8-13, Pi Starter Pack: Jack Davis
- 5-15-13, Pi Model B 512MB RAM: Patrick Dunn
- 5-21-13, Prototyping Pi Plate Kit: Philip Kirby
- Next winner announced on 5-27-13!
Free Webinar: Hadoop
How to Build an Optimal Hadoop Cluster to Store and Maintain Unlimited Amounts of Data Using Microservers
Realizing the promise of Apache® Hadoop® requires the effective deployment of compute, memory, storage and networking to achieve optimal results. With its flexibility and multitude of options, it is easy to over or under provision the server infrastructure, resulting in poor performance and high TCO. Join us for an in depth, technical discussion with industry experts from leading Hadoop and server companies who will provide insights into the key considerations for designing and deploying an optimal Hadoop cluster.
Some of key questions to be discussed are:
- What is the “typical” Hadoop cluster and what should be installed on the different machine types?
- Why should you consider the typical workload patterns when making your hardware decisions?
- Are all microservers created equal for Hadoop deployments?
- How do I plan for expansion if I require more compute, memory, storage or networking?




6 hours 5 min ago
10 hours 32 min ago
14 hours 8 min ago
14 hours 40 min ago
17 hours 4 min ago
17 hours 7 min ago
17 hours 8 min ago
21 hours 33 min ago
23 hours 24 min ago
1 day 4 hours ago