TinyTemplate – An inline perl Template system in < 30 lines of code

For me, templating systems are the itch that never stops. I’ve written templating systems is C++, Java, Perl and even Javascript (though I gave up the javascript one when I started using TrimPath’s amazing javascript template library).
The latest incarnation is TinyTemplate. This is the 4th templating system I’ve written in Perl and I think this is the one ;-). It will either make me famous or ridiculed for my naievety. I’ve got this thing about writing as little code as possible so each templating system I’ve written has had a progressively smaller codebase. This time I think I’ve hit on something: A templating system in < 30 lines of non-idiomatic Perl code. The code is a little rough around the edges (it was just written this evening). I don’t have the patience (or time) to jump through all the necessary hoops to get this thing on CPAN (as I did with TinyMake – you see a pattern here ?), so I’m presenting TinyTemplate here in all it’s glory…


package TinyTemplate;
our $VERSION = '0.01';

=head1 NAME

TinyTemplate - A Tiny Inline-Perl Template module with an execution model similar to JSP's.

Templates are strings which are converted to Perl code for evaluation.


use TinyTemplate ':all';
print "Content-type: text/html\n\n";
# parse will convert a template (in the form of a string)
# into equivalent perl code. The following sample uses Perl's here document syntax...
eval parse <<'END';
[% foreach my $row ({name=>"Walter Higgins", address=>"Cork,Ireland"},
{name=>"John Doe", address=>"Surrey,England"})
{ %]
[% } %]


TinyTemplate is a tiny template system that parses a string and converts it into Perl code.

Inline perl code must be enclosed in [% %] markers.

For example:
[% if ($age > 65) { %]
Please avail of our special offer for Senior Citizens
[% } %]

You can send directives to the parser using [%! %] markers.

For example:
[%!include "header.html" %]
will include (and parse) the content of header.html.

Currently there is only one directive (include) supported.

Everything that isn't enclosed in [% %] will be printed in double-quotes (interpolated),
so to print a variable name ...

You are connected to $hostname

...This means that if you want to include an email address in your template you should
escape the @ character like so...

<a href="mailto:walterh\@rocketmail.com">Contact</a>


# A simple CGI program
use strict;
use TinyMake ':all';
print "Content-Type: text/html\n\n";
eval include "my_template.html";

Contents of my_template.html...

[%!include "header.html" %]
[% foreach my $person ({name=>"Jane Malone",
age=> 64,

{name=>"John Doe",
age=> 68,
address=>"Surrey,England"}) { %]
[% if ($person->{age} > 65) { %]
Please avail of our Senior Citizens Offers
[% } %]
[% } %]

Contents of header.html...

<title>People List</title>


use strict;
require Exporter;
our @ISA = ("Exporter");
our @EXPORT_OK = qw(parse include);
our %EXPORT_TAGS = (all => \@EXPORT_OK,);

# Parse a string splitting it into tokens then
# joining it back to form a string which can be evaluated
# as perl code.
sub parse
my $perl = join "\n",map {
my ($enclosed, $directive, $text) = $_ =~ /(\[%)*(!)*(.+)/s;
if ($directive){
my $evald = eval $text ;
die $@ if $@;
$_ = $evald;
}elsif ($enclosed){
$_ = $text;
$text =~ s/\n/\\n/g;
$text =~ s/"/\\"/g;
$_ = "print \"$text\";";
} split /(\[%.*?)%\]/s, $_[0];
# Include content from another file for evaluation
sub include
my ($filename) = @_;
open FILE, $filename or die "COULDN'T OPEN FILE $filename because $!\n";
my $contents = join '', <FILE>;
close FILE;
parse $contents;


P.S. I’m sure a Perl Wizard could trim this down to a one-liner. A one-liner templating system that supported inline perl would be cool. Any takers ?


One thought on “TinyTemplate – An inline perl Template system in < 30 lines of code

  1. Pedro Borges says:

    Hi, could you share the tinytemplate again.


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s

%d bloggers like this: