Progressive enhancement with PerlTemplates

Posted Sunday, April 26th at 1:29p.m. under Perl, Code, Javascript


I've just created my first repository on github: PerlTemplates. PerlTemplates is a JavaScript template engine which uses the same syntax as the Perl template engine HTML::Template. Why would you need something like this?

Well hopefully you are aware of the importance of progessive enhancement; and if, like me, you work on web applications where you just can't ignore those who have disabled JavaScript in their browsers then you'll also be aware of the banality of creating both JavaScript and non-JavaScript versions of your slick AJAX interfaces.

Some of the common ways of getting round this that I've seen from other developers have been to return HTML (as opposed to returning XML or JSON) and inject that directly into the DOM, or to create the DOM elements in the Javascript code itself. Both methods have their drawbacks: as soon as you've got HTML creation in the Javascript code you now need to maintain markup in two seperare locations. Returning HTML doesn't have this problem, but for complex situations you rarely want just presentation back - you need data.

Using PerlTemplates has allowed us to follow the principles of DRY, and it has made progressive enhancement quick and simple. To illustrate, the 'output' of a search results script (which is a prime candidate for AJAXification) might look like this:

        
my $template = HTML::Template->new('/path/to/search/results.tmpl');
$template->param(%values); # where values contains the template data structure
print CGI->header, $template->output();

Well, to make it PerlTemplates-ready, we simply add a condition which returns JSON in the event of an AJAX request (which can be detected in various different ways):

if($ajax_request)
{
print CGI->header, JSON->new->encode(%values);
}
else
{
my $template = HTML::Template->new('/path/to/search/results.tmpl');
$template->param(%values);
print CGI->header, $template->output();
}

Then in our Javascript, we have code that looks like this (using jQuery):

$.getJSON('/search/results', function(json_data) {
var tmpl = new PerlTemplates({url:'results.tmpl', data: json_data, target: 'search-results'});
tmpl.render();
}

That's all there is to it. The one drawback to this approach is that your templates must be made available over HTTP, which might be tricky if your templates are stored outside of your root web directory (or you're a fan of security by obscurity).

Download

PerlTemplates has no dependencies and the minified version comes in at just over 5kb. You can see it in action here and download the package from here. PerlTemplates has been tested in all major browsers, and is currently in use on sites serving millions of pages per month.

Posted by David McLaughlin on Sunday, April 26th

Leave a Reply