EJS Syntax Reference
====================

EJS is designed to be flexible and easy-to-write, but without too much
abstractions to cover up the HTML base.

Table of contents
-----------------

- Basic format
- Delimiters
- Starting tags
  - `<%=`: Escaped output
  - `<%-`: Unescaped output
  - `<%#`: Comments
  - `<%`: Scriptlets
- Ending tags
  - `%>`: Regular ending tag
  - `-%>`: Whitespace-trimming ending tag
- Literal tag
- Including other files
  - “Preprocessor” directive
  - JavaScript `include()` function
- Copyright


Basic format
------------

An EJS “tag” is the primary functioning unit in an EJS template. With the
exception of the literal tag, all tags are formed by the following format:

<pre>&lt;<em>starting</em> <em>content</em> <em>closing</em>&gt;</pre>

The spaces between *starting* and *content*, and *content* and *closing* are
not required; they are recommended though for readability.

Delimiters
----------

The *starting* and *closing* tags contain a special string called the
delimiter. In this document, all tags are shown using the `%` delimiter, which
is the default. You can, however, change that to your liking. See api.md for
more information on how to change it.

Starting tags
-------------

### `<%=`: Escaped output

The most important thing for a template language is the ability to pass
variables to the template. In EJS, this is done with the `<%=` and `<%-` tags.

`<%=` is the starting tag to use for variables that need to be escaped. If the
specified string contains forbidden characters like `<` and `&`, they are
escaped automatically with HTML codes.

The content of the tag can be any valid JavaScript operators, so tags like
`<%= name ? name : (lastName || 'John Doe') %>` would work as intended.

#### Example

##### EJS

```html
<p>Hello, <%= name %>.</p>
<p>Hello, <%= 'the Most Honorable ' + name %>.</p>
```

##### Locals

```json
{
  "name": "Timoth<y>"
}
```

##### HTML

```html
<p>Hello, Timoth&lt;y&gt;.</p>
<p>Hello, the Most Honorable Timoth&lt;y&gt;.</p>
```

### `<%-`: Unescaped output

If your local contains preformatted HTML, you might not want to escape it. In
this case, use the `<%-` tag.

However, always **be 100% sure** the rendered local is sanitized, to prevent
cross-site scripting (XSS) attacks.

#### Example

##### EJS

```html
<p>Hello, <%- myHtml %>.</p>
<p>Hello, <%= myHtml %>.</p>

<p>Hello, <%- myMaliciousHtml %>.</p>
<p>Hello, <%= myMaliciousHtml %>.</p>
```

##### Locals

```json
{
  "myHtml": "<strong>Timothy</strong>"
, "myMaliciousHtml": "</p><script>document.write()</script><p>"
}
```

##### HTML

```html
<p>Hello, <strong>Timothy</strong>.</p>
<p>Hello, &lt;strong&gt;Timothy&lt;/strong&gt;.</p>

<p>Hello, </p><script>document.write()</script><p>.</p>
<p>Hello, &lt;/p&gt;&lt;script&gt;document.write()&lt;/script&gt;&lt;p&gt;.</p>
```

### `<%#`: Comments

The `<%#` starting tag denotes that the statement is a comment that is not to
be executed or rendered in the resulting HTML.

#### Whitespace

The use of `<%#` might cause some useless whitespace, as illustrated by the
example below. You can trim it using the `-%>` ending tag.

#### Example

##### EJS

```html
<p><%# comment %></p>
```

##### HTML

```html
<p></p>
```

### `<%`: Scriptlets

Scriptlets in the `<%` tag allows logic to be embedded in an EJS template. You
are free to use *any* JavaScript syntax in this tag, and to mix JavaScript
with EJS. You can also put multiple statements in one tag.

#### Comments

All types of JavaScript comments are allowed, although it is preferable to use
the `<%#` tag for comments. For example, the following three code blocks are
equivalent, though `<%#` is the shortest.

```js
<%# comment %>
<%/* comment */%>
<%// comment %>
```

#### Curly brackets

Always use brackets in loops and conditionals that involves mixing EJS
template and JavaScript scriptlets. Omitting brackets might work for some
statements, but the behavior is undefined and subject to change.

It is not necessary to use curly brackets for scriptlet-only code.

```html
<%# Bad practice %>
<% if (true) %>
  <p>Yay it's true!</p>

<%# Good practice %>
<% if (true) { %>
  <p>Yay it's true!</p>
<% } %>
```

```js
<%# These are all valid statements %>
<% var output
     , exclamation = ''
     , shouldOutput = false

   if (true)
     output = 'true!'

   if (true) {
     exclamation = 'Yay! ';
   }

   if (true) shouldOutput = true; %>

<% if (shouldOutput) { %>
  <%= exclamation + 'It\'s ' + output %>
<% } %>
```

#### Line breaks inside a tag

Line breaks are allowed in `<%` tags.

Unless the statement involves mixing EJS and JavaScript scriptlet, always put
complete statements in a tag. For example, the following works:

```js
<% var stringToShow = thisIsABooleanVariableWithAVeryLongName
                    ? 'OK'
                    : 'not OK' %>
```

While the following does not:

```js
<% var stringToShow = thisIsABooleanVariableWithAVeryLongName %>
<%                  ? 'OK'                                    %>
<%                  : 'not OK'                                %>
```

#### Semicolons

As is in JavaScript, semicolons are not required if proper line breaks are
preserved.

#### Whitespace

The use of scriptlets might cause some useless whitespace, as illustrated by
the example below. You can trim it by

1. using the `-%>` ending tag, and
2. always starting the tag in the beginning of a line.

#### Example

In the following example, several different coding styles are used
simultaneously, to show that EJS is flexible with regards to personal habits.
It does *not* mean that we recommend mixing coding styles in your own project.

##### EJS

```html
<dl>
<%for (var i = 0; i < users.length; i++) {    %><%
  var user = users[i]
      , name = user.name // the name of the user
    %><%# comment %>
  <%var age  = user.age; /* the age of the user */%>
  <dt><%= name %></dt>
  <dd><%= age %></dd>
<%}-%>
</dl>
```

##### Locals

```json
{
  "users": [
    {
      "name": "Timothy"
    , "age":  15
    }
  , {
      "name": "Juan"
    , "age":  51
    }
  ]
}
```

##### HTML

```html
<dl>



  <dt>Timothy</dt>
  <dd>15</dd>



  <dt>Juan</dt>
  <dd>51</dd>

</dl>
```

Ending tags
-----------

There are two flavors of ending tags: the regular one and the
whitespace-trimming one.

### `%>`: Regular ending tag

As used in all of the examples above, `%>` is the standard tag used to end an
EJS expression.

### `-%>`: Whitespace-trimming ending tag

`-%>` trims all extra whitespace a scriptlet or a comment might cause. It does
not have any effect on output tags.

#### Example

This is the exact example from `<%` starting tag above, but with `%>`
substituted by `-%>`.

##### EJS

```js
Beginning of template
<%  'this is a statement'
 + ' that is long'
 + ' and long'
 + ' and long' %>
This is indented so some spaces will still be left:
  <% 'statement' -%>
See?
This is the proper way:
<%   'statement' -%>
End of template
```

##### Output

```
Beginning of template

This is indented so some spaces will still be left:
  See?
This is the proper way:
End of template
```

Literal tag
-----------

To output a literal `<%`, use `<%%`. If a customized delimiter is used, use
the same syntax. E.g. use `<$$` to get `<$` if the delimiter is `$`.

In regards to all the other tags, the literal tag is special as it does not
need a closing tag to function.

However, think twice before you use this tag because the `<` character might
need to be escaped as `&lt;`.

#### Example

The following example wrap `<%` in a `<pre>`, where it is not necessary to
escape `<`.

##### EJS

```html
<pre>This is literal: <%%</pre>
<pre>This is literal too: <%% %></pre>
```

##### HTML

```html
<pre>This is literal: <%</pre>
<pre>This is literal too: <% %></pre>
```

## Including other files

EJS offer two ways of including other files. You can even include files that
are not EJS templates, as the case is for CSS stylesheets.

### “Preprocessor” directive

As a compatibility layer with EJS version 1, it is possible to use the
`include` directive in an unescaped output tag to directly “yank” the
text from another file, just like including a C header. However, as it is done
as a simple inclusion, you cannot pass arguments to the included template. You
can however make variables available in the parent template, that will be
visible to the child template as well.

This flavor of `include` is **static**, which means that the resulting
function contains the copy of the included file as when it was compiled, so
if you changed the file after compilation, the changes are not reflected.

If the file specified has an extension and is an absolute path, that file is
included. If it does not have an extension, `.ejs` is automatically appended.
If the file is not an absolute path, the file is searched in the same
directory as the parent template’s.

#### Whitespace control

You most probably should not use the `-%>` ending tag on an `include`
directive, as it trims the whitespace after the included file.

#### Example

##### included.ejs

```html
<li><%= pet.name %></li>
```

##### main.ejs

```html
<ul>
<% pets.forEach(function (pet) { -%>
  <% include included %>
<% }) -%>
</ul>
```

##### Locals

```json
{
  "pets": [
    {
      "name": "Hazel"
    }
  , {
      "name": "Crystal"
    }
  , {
      "name": "Catcher"
    }
  ]
}
```

##### “Preprocessor" output

```js
<ul>
<% pets.forEach(function (pet) { -%>
  <li><%= pet.name %></li>
<% }) -%>
</ul>
```

##### HTML

```html
<ul>
  <li>Hazel</li>
  <li>Crystal</li>
  <li>Catcher</li>
</ul>
```

### JavaScript `include()` function

With the release of EJS version 2, we have added a new way of including files
that is more intuitive. The `include()` function is available to the
templates, with the following signature:

```js
include(filename, [locals])
```

One major difference with the method described above is that the variables in
the parent function are not visible to the child template, unless it is
explicitly declared in the `locals` object, or is passed as a local to the
parent template.

Also, the included file is compiled upon execution of the script, which means
performance might be theoretically lower than the “preprocessor” flavor. In
practice however, caching can make this difference negligible.

#### Example

This has the exact same effect as the example for the `include` directive.

##### included.ejs

```html
<li><%= pet.name %></li>
```

##### main.ejs

```html
<ul>
<%  pets.forEach(function (pet) { -%>
  <%- include('included', {
        pet: pet
      }) %>
<%  }) -%>
</ul>
```

##### Locals

```json
{
  "pets": [
    {
      "name": "Hazel"
    }
  , {
      "name": "Crystal"
    }
  , {
      "name": "Catcher"
    }
  ]
}
```

##### HTML

```html
<ul>
  <li>Hazel</li>
  <li>Crystal</li>
  <li>Catcher</li>
</ul>
```

## Copyright

This document is under the following license:

Copyright © 2015 Tiancheng “Timothy” Gu

Licensed under the Apache License, Version 2.0 (the “License”); you may not
use this file except in compliance with the License. You may obtain a copy of
the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an “AS IS” BASIS, WITHOUT
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
License for the specific language governing permissions and limitations under
the License.
