Portrait Dr. Axel Rauschmayer
Dr. Axel Rauschmayer
Homepage | Twitter
Cover of book “Exploring ES6”
Book, exercises, quizzes
(free to read online)
Logo of newsletter “ES.next news”
Newsletter (free)
Cover of book “JavaScript for impatient programmers”
Book (free online)

Improving the syntax of EJS templates

[2016-09-10] dev, javascript
(Ad, please don’t block)

I really like the way EJS templates work, because the meta-language (loops, if-then-else, etc.) is just JavaScript. This blog post describes ideas for improving their syntax.

EJS templates  

This is an example of an EJS template:

<ul>
<% for(var i=0; i<supplies.length; i++) { %>
   <li><%= supplies[i] %></li>
<% } %>
</ul>

I see two problems with this template:

  1. It outputs empty lines for line 2 and 4.
  2. The delimiters <% and %> make the template look cluttered.

Suppressing whitespace  

The first problem can be fixed by using the delimiters <%_ and _%> which suppress any whitespace generated by that line:

<ul>
<%_ for(var i=0; i<supplies.length; i++) { _%>
   <li><%= supplies[i] %></li>
<%_ } _%>
</ul>

Better control flow syntax  

If control flow syntax is enabled by a single character at the beginning of a line then the template looks much nicer:

<ul>
# for(var i=0; i<supplies.length; i++) {
   <li><%= supplies[i] %></li>
# }
</ul>

The way to get this syntax is via a work-around – use a regular expression to convert:

# foo

to:

<%_ foo_%>

For example:

template = template.replace(/^[ \t]*#(.*)$/mg, '<%_$1_%>');

This regular expression allows the # to be indented:

<html>
    <body>
        # for(var i=0; i<supplies.length; i++) {
           <li><%= supplies[i] %></li>
        # }
    </body>
</html>

One more improvement  

Additionally, there is an issue for letting people change the delimiter <% to something different. Then the template could look like this:

<ul>
# for(var i=0; i<supplies.length; i++) {
   <li>{{= supplies[i] }}</li>
# }
</ul>

I find that easier to read, given that the delimiters are surrounded by HTML with lots of angle brackets.