StringTemplate for JavaScript

About three weeks ago I announced on the StringTemplate discussion forum that I had updated my StringTemplate Standalone Tool (STST) to work with StringTemplate version 4. It has been a number of years since I have used StringTempalte and almost as many since I’ve programmed in Java. So why this return to StringTemplate and Java? My motivation for updating STST is that I intend to create a pure JavaScript implementation of StringTemplate.

So far my work with JavaScript has mostly been creating UI widgets as part of existing web apps and frameworks. I have not had a need for templates, at least not ones processed by JavaScript. That may change with my Climbing Comp project and some other code generation projects I have in mind.

What I’m looking for in a JavaScript template engine:

  • Strong separation of presentation and logic
  • Compiled templates, good performance
  • Mostly need to run on the server using node.js but running in the browser is a plus
  • Can generate any text format, not just HTML

The best match I found is Handlebars. It compiles to JavaScript, runs in the browser and node.js environments, and does a decent job of keeping logic out of the templates. It seems focused on HTML generation but I think it could work for other text formats. I have only played with it a little. There are a few things that I don’t like. Having to write helpers in JavaScript and the way partials are handled distinct from templates doesn’t seem as nice as StringTemplate. Handlebars doesn’t have the separate renderer and writer layers that StringTemplate has. I didn’t do a detailed analysis of the differences between Handlebars and StringTemplate. My gut tells me that I would prefer StringTemplate.

Because, at least initially, I plan to do generation off-line on the server side I could use the Java version of StringTemplate but I would prefer not to add Java to the tool chain; so far I have been able to do everything I need with node. This is what has brought me to creating StringTemplate for JavaScript.

StringTemplate for JavaScript (StringTemplatet-js) will compile templates to JavaScript. It will not have an interpreter. It should be 100% compatible with StringTemplate v4 template syntax and semantics. The API will be different.

To implement StringTemplate-js will require parsing template files and generating JavaScript code. The former would be a good job for ANTLR and the later well suited to StringTemplate. ANTLR can generate JavaScript code but again I would rather not have to use Java. This lead me to try two JavaScript parser generators: jison and pegjs.

I tried jison first and it was a failure. Any syntax error in the grammar resulted in a generic exception with no indication of what went wrong or even the line number. I found my errors by selectively commenting out code until the problem line was isolated. The generated code was extremely difficult to understand and debug. Then when I tried examples right out of the documentation that didn’t work I gave up.

Now I’m using pegjs and it is working very well. The error reporting is very good and the parser it generates also has very good error reporting including source line and column. One minor issue is that it stops at the first error. The generated code is not as readable as what ANTLR3 generates but it is reasonable and I have had no problem debugging it. Not having a separate lexer and parser takes some getting used to. It means having to represent white space throughout the grammar because you can’t just toss the tokens out in the lexer. Some of the things I thought would be difficult, such as having configurable start and stop template delimiters, turned out to be quite easy to deal with.

StringTemplate-js will use itself to generate the compiled template JavaScript code. This is where STST comes in. I plan to use it to bootstrap the process. It will also come in handy in validating that StringTemplate-js gets the same answer as the Java reference implementation.

Hopefully soon JavaScript will have another template engine option. Watch this space.