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:
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 }
{ 1 comment… read it below or add one }
Pretty sure I didn’t know you had this blog :p Following it now