Thursday, December 11, 2008

Liquid.js, A Non-Evaling Template Engine in JavaScript

Of late, I’ve needed a robust JavaScript template engine that doesn’t use eval (and preferably not with). Also, I’ve always liked Liquid.

So, two plus two equals… JavaScript! Hah, you thought it was four, didn’t you? Well, that’s what you get for thinking.

Yeah, long story short, I ported Liquid to JavaScript. You can grab it from github (where else?) here:

I’m calling this version 0.1. It’s not battle tested yet, but I know it’ll work using Firefox 3+, Safari 3+, and Adobe Air 1.1.

So what are the differences between running the Ruby version and the JavaScript version? Well, as far as the templates themselves, nothing. It’s a full port, so all of Liquid’s default tags and filters are supported in Liquid.js. I even added a placeholder function that you can implement yourself (based on your own needs) to support the ‘include’ tag.

Liquid.readTemplateFile = function(path) {
  var elem = $(path);
  if(elem) {
    return elem.innerHTML;
  } else {
    return path +" can't be found."; 
    // Or throw and error, or whatever you want...

var src = "{% include 'myOtherTemplate' with current_user %}";

var tmpl = Liquid.parse( src );

alert( tmpl.render({ current_user:'M@' }));

An easy way to include template in a page is to use script elements, like this:

<!-- Browsers ignore script blocks with an unrecognized type.  -->
<!-- Makes for pretty good inline template storage.  -->
<script type="text/liquid" id="myOtherTemplate">
  Hello, {{ current_user }}!

Currently, Liquid.js requires MooTools. Some of the things I’d like to polish up:

  • Remove MooTools requirement, run entirely independent of any other js library
  • Add Rhino for console-based testing
  • Test, test, test on Internet Exploder Explorer