Writing JavaScript templates using ejs

There are quite a few (as you’d probably expect) templating engines for use with JavaScript, such as Mustache and handlebars both of which use {{ }} syntax.

The syntax used is really not very important, what matters is the flexibility/functionality, but for nostalgia’s sake (as much as anything) this post will instead use ejs which uses syntax such as <%= %> which is very much like old ASP from my recollections (hence the nostalgia).

Note: I’m not endorsing ejs over any other engine, I just picked this to begin with, if/when I get time I will probably create posts covering using some other templating engines also.

Getting Started

We need to start by installing ejs, so run the following

yarn add ejs

We’re going to create a folder named templates (this is not a requirement of ejs) to store our .ejs files. So the template files will be saved with the .ejs extension.

Let’s just create a very standard Hello World app. so in the file templates/sample.ejs write the following

<%= message %>

Now let’s write the code to use ejs generate some output from our template and supply our data to the generator.

const ejs = require("ejs");

ejs.renderFile("./templates/sample.ejs", {
    message: "Hello World",
  },
  {},
  (err: any, result: string) => {
    if(err != null) {
      console.log(err);
    }
    // use the results of the template combined
    // with the supplied model
    console.log(result);
});

Here we show the basic usage pattern, which uses the asynchronous renderFile function. This takes the template file (we can ofcourse also supply the template as a string using the render function). The second argument is a “model” of the data being passed into the template engine and ofcourse the key’s related to the variable names used within the template file. The third argument supplies any options to the template engine, in this example I’m not applying any options. Finally, as this function is asynchronous, we will get an error or result or the processing of the template.

More…

That was simple enough but we’re not going to want to just output simple values like this, so let’s take a look at some more capabilities.

If we take a look at the Docs (https://ejs.co/#docs), Tags section we can see the tags for embedding our model data, let’s take a look at some of these in usage.

<%

The scriptlet tag is used for flow control and does not embed output into the template itself (as such). Instead it allow us to use conditionals such as if or loops such as for loops on our data model items.

type Names = <% for(let i = 0; i < names.length; i++) { %>
    | '<%= name[i].header %>'<% } %>;

In this example we’re code generating some types by taking an array of names from the model and creating a union of those header names.

Like-wise we might also use this tag for if statements within the <% %gt;

<%_

This will strip whitespace from before the tag. One of the problems we often find with templated code generation is how to control whitespace before and after the generated code. Hence this will remove the preceding whitespace.

<%=

This simply embeds an HTML escaped value into our template, in other words it simply replaces the tag with the value from message in this example below. Ofcourse message is a value stored in our data model.

<%= message %>

<%-

As per <%= but no escaping of values takes place.

<%#

Comment tags, just in case you wanted to add some comments/documentation to your template, this does not get output as part of the generated data.

<%%

Escapes the tag, i.e. outputs <%

%>

Standard end tag for use with the other start tags.

-%>

Trims the following newline.

_%>

Removes whitespace after the tag, again allows us to have some control of the whitespace following our generated output.