Enabling Templates in Client-Side JavaScript with CJSC

In spite of most server-side languages JavaScript was not designed for templates. Yet we have plenty of template engines for client-side JavaScript now. They allow us processing templates, but what about declaring a template?

As you know JavaScript doesn’t provide a decent way to assign a multiline text to a variable. Well, you can go with string spitted by back-slashes, but in this case a trailing space would break your JavaScript. You can use heredoc notation of JavaScript 1.6 / E4X and again it will be quite fragile. You can use "\n\" line endings when browser supports them, yet it makes a clumsy template. On the other hand you can place the template code directly into HTML body wrapped with script element and obtain its content from JavaScript. It works fine, but doesn’t encourage a good architecture. The most suitable pace for a template is a separate file, isn’t it? Well, how do we get its content from JavaScript? AJAX? An HTTP request per template then?


Retrieving a template with CJSC

As pointed out in the last article that JavaScript can be kept modular without hurting application performance. What about templates? When ran into a non-JavaScript text file the CommonJS Compiler treats this dependency as a text string. It means you can obtain template content in JavaScript as simple as that:

var tpl = require( "./template.txt" );
console.log( tpl );

How does it works with template engines?


Let’s take Mustache. We download mustache.js and place it in a test directory along with template file example.tpl:

{{title}}
spends {{calc}}

Now we create a module, which reads and populates the template example.js:

var mustache = require( "./mustache" ),
		tpl = require( "./example.tpl" ),
		view = {
			title: "Joe",
			calc: function () {
				return 2 + 4;
			}
		};

console.log( mustache.render( tpl, view ) );

Since mustache.js is UMD-compatible, we can request it using require.


To compile the module we run the following:

cjsc example.js build.js

When executing build.js we get the results:

Joe
 spends 6

What about a non-UMD templating engine?


This time we will try to use Handlebars. Again we download the library and create a template example.hbs:

<div class="entry">
  <h1>{{title}}</h1>
  <div class="body">
    {{body}}
  </div>
</div>

Here goes usage example:

var handlebars = require( "./handlebars", "Handlebars" ).Handlebars,
		tpl = require( "./example.hbs" ),
		view = {
			title: "My New Post",
			body: "This is my first post!"
		};

console.log( handlebars.compile( tpl )( view ) );

Handlebars.js exposes itself as global property Handlebars. So we specify in the require call that this variable must be exported.