Rick

Rick
Rick

Monday, March 10, 2014

Adventures in Handlebars

Last night I rewrote the core Boon handlebars parser. Early days....

I rewrote the handlebars  parser as a recursive descent parser into a full index overlay.

It would have gone a lot faster if I knew what the hell I was doing. 
The core works. Now I have to marry the core parser to the template engine. I have to finish it too.

The existing template engine works but does not allow nested {{if #}}  {/iff}} or nested loops, etc.. Thus the rewrite of the parser.  It was 4:00 AM one day, and I was adding some edge case unit tests when I realized that I needed to rewrite the parser from scratch after a few hours of debugging and hacking. Some people learn by reading a tutorial. I learn by implementing it and making mistakes.

I did not fully grok handlebars when I wrote it the first version. I was just fooling around with a line oriented approach. The parsing was a dirty hack and I knew it. I was just looking for a simple/easy implementation but you can't defy gravity for very long.  The rewrite looks more like the Boon JSON parser that I wrote so it is a full recursive descent parser.

Not a total screw up on the first attempt, but I wrote everything else well, function handlers, expression handlers, body handlers, if handler, with handler, loop handler, and a few extra I just made up. I was quite proud of it until I tried to nest an #if inside of a #loop (days later), and then realized after a few hours of debugging my quick and dirty parser needed to be rewritten from the ground up. It actually only took a few hours to write the core of the parser. 

So in a week or two, ... Boon will have a full handlebars implementation with 40 gazillion built-in functions..
It should be the fastest and easiest to use as well. (It has one now as long as you never nest #if, #loop commands so in does *not* have one now).

I am also implementing a JSTL style template engine ala Facelets and a Velocity and Freemarker one.

So you can 



<c:if test="${foo}">

    ${foo}

</c:if>

Or mustache/handlebar

{{#if  foo}}

    {{foo}}

{{/if}}

Or freemarker

<#if  foo >

      ${foo}
</#>

Or  Velocity

#if  foo 

      ${foo}

#

Of course the JSTL, Freemarker and Velocity versions will just be JSTL-like, Freemarker-like and Velocity-like.

My idea is to make it easy for people to learn and perhaps switch. (I am not pushy on the switch thing.)

The core engine will be the same, i.e., it will be the Boon Mustache engine which is sort of Mustache++ or will be (maybe). Just the parser will vary for flavors. The template engine will be the same.

The goal is mustache/handlebar compatibility with flavors easily digestible by Java developers. I take my inspiration for the JSTL flavor from Facelet of which I was an early adopter. 

So now I have written 8 to 10 handwritten recursive descent parsers in the past year (PLIST, JSON-LAX, 6 flavors of JSON and now mustache, and JSTL markup). I have been avoiding writing an expression language which I need in various places. Boon has path expressions, but what it really needs is XPath/JsonPath expressions. I also need a SQL like query language for data repo so I can reuse the expression parser if needed. I reckon there are at least two more parser left in me this year. I need to finish the JSTL template (I might rename this to Boon Template markup so as not to get sued), Velocity-like (Velociraptor template so not to piss off Velocity guys too much), and Freemarker (Woodstock (as in free love) template).  I need more coffee.

Many years ago, I wrote a basic parser (descent parser), and C light basic parser. Well... I hacked around with examples from Power C and Love C from Herbert Schildt.I never dreamed I would actually write several more 20 years later. 

No comments:

Post a Comment

Kafka and Cassandra support, training for AWS EC2 Cassandra 3.0 Training