Simple Template System in Perl

September 11, 2009

By now you should know I am a fan of everything simple. I casted an opinion that frameworks, while useful, are overcomplicated and create an unnecessary load on your project, unless it reaches a certain amount of complexity. And one of the most used frameworks, are the template frameworks. Thus, it would be great to have a dead simple template system, that just works. And that’s what I am going to show you today.

Because Perl is my weapon of choice, I’m going to show you my Simple Template System (STS) for that language, but porting it to another one shouldn’t be a problem. The idea is simple, of course, and relies on creating a traditional HTML file, as if creating the general look of the site, and then instead of content, marking it with special string, which we then substitute with whatever we want, using regular expressions.

So you start off with a simple HTML page, for example:

<html>
<head>
<title>Simple Template System</title>
</head>
<body>
<div class=”menu”>
<!---sidebar--->
</div>
<div class=”main”>
<!---content--->
</div>
</body>
</head>

The <! — sidebar — > and <! — content — > are those special strings for substitution. The purpose of using a HTML comment symbol with an additional hyphen is that first of all, they are invisible if left behind in the code, second — it’s easy to regex them from ordinary comments, and third — they are valid HTML. So now we have a page skeleton, or in other words — a template. It’s time to use it.

For this purpose, we’ll have a simple Perl script that reads the template file, lets call it main.tmp, and substitutes the necessary stuff to display a content-rich site. First we load the template into a variable:

my $tmp = ‘’;
if( open FILE, ‘<’, ‘main.tmp’ ){
while( <FILE> ){ $tmp .= $_; }
close FILE;
}

To walk you through the code, I’ll just say that we first try to open the file in the read-only mode, then we go over all the lines in that file and append them to the $tmp variable, and in the end we close that file.

Then we define content variables and give them some values:

my $sidebar = ‘This is a menu’;
my $content = ‘This is the main content block’;

Finally, we put the content in the necessary places using regular expressions, and we print the website:

$tmp =~ s/<!---sidebar--->/$sidebar/;
$tmp =~ s/<!---content--->/$content/;
$tmp =~ s/<!---.*?--->//g;
print CGI::header( -type => ‘text/html’ );
print $tmp;

The s/ is a regular expression substitution. The first argument is the string to look for, the second argument is the string to put instead of the first one. So we simply look for sidebar and main content placeholders, and substitute it with the actual content. The last regular expression removes all other placeholders that we won’t be using in this case — because this template system is flexible, you can have a lot of place holders, not all need to be used. And what about placeholders within placeholders? Well you could use them, you would just need a more fancy regular expression. I can’t think of a reason to have such a thing, but why not :]

UPDATE: draegtun of transfixedbutnotdead picked up the STS subject in a clever post on how features can kill usability, but had a very good idea of making the initial code slicker by using a hash table and a single regex. So, instead of defining variables separately, we use a hash:

my %vars = {
sidebar => ‘This is a menu’,
content => ‘This is the main content block’
}

And instead of separate regular expressions, just a single one:

$tmp =~ s/<!---(.*?)--->/exists $vars{$1} ? $vars{$1} : ‘’/ge;

The above regex looks for the placeholders, and if the placeholder name matches any of our keys in the hash that contain data to be displayed — we make a substitution. Otherwise, we remove the placeholder from the displayed page.

Conclusions

And there you have it — a Simple Template System that you can setup within minutes just by coding by hand, and quickly create a variable-content websites. Using if statement you could make a page that displays different content basing on which section the user wants to see. Finally, you could have several different template files, changing them according to your needs (for example, front page different then subpages, article pages, etc.)


Originally published at web.archive.org.