You can find me on twitter via @carl_furrow

Javascript HTML Templating: EJS vs JAML

by Carl on January 21, 2010

Now that I’ve played around with EJS for a while, I can say I’m fairly comfortable with it, and love the syntax. It just makes sense to me. But recently, I came across another templating framework, called JAML, or HAML for Javascript (GitHub Page), and it addresses one of my main concerns with EJS. I’ll get to what that was in a little bit. First, let’s look at some JAML syntax:

JAML Syntax

Example of JAML syntax

Pretty nice, eh? And it’s still easily tucked-away separate from your functional Javascript code. You could create a JS file for each template object, i.e. “Products.jaml.js”, “Orders.jaml.js”, etc, then include them on the page before you require the rendered output/HTML in your functional code.

One of the problems I was running into with EJS was that I needed to make sure the paths to my .ejs files were always correct, regardless of the page the user was looking at. So I had to create absolute URL references to the EJS file via directly, “/somepath/someotherpath/products.ejs”. And that’s fine, but I had more than a few issues while debugging since my production environment was at http://somesite.com and my local site was at http://localhost/myproject/. So when my code asked for “/somepath/someotherpath/product.ejs” it would work fine in production, but it would fail in JS. I came up with ways to use a variable that would get me to the right path, so it’s wasn’t insurmountable, but it was something to keep in mind. Obviously, JAML fixes that by keeping your templates as regular Javascript that can be put into .js files and included in regular <script/> blocks. Nice.

Now let’s do the same comparison I did for jQuery vs EJS. First we start off with a products array.

var products = [
{
id:0,
desc:"product 0",
price: 10.50
},
{
id:1,
desc:"product 1",
price: 1.25
},
{
id:2,
desc:"product 2",
price: 5.60
}
];

And since you’ve already seen what EJS looks like, here’s the JAML syntax:

Jaml.register('product',function(pProduct){
li({cls:"product"},
a({href:"/product/"+pProduct.id},"product "+pProduct.id+" ($"+pProduct.price+")")
);
});

Jaml.register('products',function(pProducts){
ul({cls:'products'},Jaml.render('product',pProducts.products));
});

You’ll notice that I had to do this in a two-step process (i.e. two calls to the register() method). This is a limitation of how the collections/partials process works. I created a template for what an individual product looks like, then I created a template to how a collection of products works; inside of a UL tag, with a product partial for each product object inside of pProducts.products. Not too bad, but it’s a little more work vs EJS, but, if you think about it in the “partials” methodology, it’s not a bad mental-leap.

And the output is as it should be:

<ul class="products"><li class="product">
  <a href="/product/0">product 0 ($10.5)</a>
</li>
<li class="product">
  <a href="/product/1">product 1 ($1.25)</a>
</li>
<li class="product">
  <a href="/product/2">product 2 ($5.6)</a>
</li>
</ul>

Definitely going to have to try out JAML on some of my larger projects to see how it fairs. I imagine it’ll do very well. Thanks to Ed Spencer for this cool product!

{ 1 trackback }

Jaml updates : Ed Spencer
January 29, 2010 at 4:49 am

{ 1 comment… read it below or add one }

bigred February 11, 2010 at 12:21 pm

Pretty sure I didn’t know you had this blog :p Following it now :)

Leave a Comment

Previous post: