minitemp

2.1.1 • Public • Published

minitemp

Tiny, Fast and Flexible Template Engine, using Embedded Javascript.

This is a variant of the traditional EJS templating system that is compatible with it at the basic syntax level while providing additional features.

It allows your site or application to render templates in the browser (client-side) or in the server (with Node.js) using an enhanced dialect of JavaScript as the templating language.

Compared to other template systems, this library is very small and lightweight, but it's also very fast and has enough features for most templating needs. Furthermore, it allows you to easily extended it to suit your own needs.

Features

Feature highlights
  • It's TINY! (~3Kb minified; ~2Kb with gzip compression).
  • It's FAST! It compiles templates to pure javascript and automatically caches them.
  • It's compatible with the EJS syntax.
  • It has no dependencies.
  • Provides a jQuery plugin (if jQuery is available).
  • Runs in the browser or in the server (Node.js).
  • Supports AMD, CommonJS and browser globals.
  • It's extensible! - add your own templating helper functions and language extensions (macros).
Other features
  • Supports macros, which allow javascript language extensions.
  • Supports contexts, which function as global scopes for code running inside templates. They allow sharing data and functions between templates without touching the browser's global scope.
  • It has a small built-in API of utility/helper functions that you can use on your templates.
  • It can output both raw HTML (if explicitly stated) or secure escaped strings, which protect your app from code injection attacks or undesirable HTML formatting embedded in user-provided content.
  • The start and end tags can be configured (ex. use {{ }} instead of <% %>).

EJS Syntax

Embedded javascript statements

<% javascript code %>

Examples

The right way:

<div><% if (x > y) { %><p>It's bigger</p><% } else ++x %></div>

Don't do this:

<div><% if (x > y) %><p>It's bigger</p><% else ++x %></div>

While omitting curly brackets may work sometimes, it's risky. Always use them to enclose blocks in conditions, loops and other javascript control flow structures.

Expressions are ignored. For example, the following will be evaluated as a statement and its value discarded:

<div><% 'Hello' %></div>

Output safe (HTML encoded) text from javascript

<%= javascript expression %>

Example
<p>Hello <%= person.name %></p>
<div><%= person.isNice ? "Thank your for coming" : "" %></div>

Output raw HTML from javascript

<%== javascript expression %>
or
<%- javascript expression %>

Example
Hello <%== '<b>' + person.name + '</b>' %>

Comments

<%# any text %>

These comments will not generate any output.

Example
<%# Main Section %>
<h1>Title</h1>

Installation

Installing with bower

You can use Bower for installing the librar for client-side use.

$ bower install minitemp

Installing with npm

You can use npm for installing the library for server-side use.

$ npm install minitemp

Installing manually

Download the source code and copy the minitemp.min.js file into your project.


Loading the script

Client-side - as a global script

You can load the script directly with a <script> tag or you may use a script loader.

The minitemp API will be available as a global minitemp object.

Client-side - as an AMD module
define (['minitemp'], function (minitemp) {
  // your code here
});
Client-side or Server-side - as a CommonJS module
var minitemp = require('minitemp');

You can load the library as a CommonJS module either client-side (using Browserify or any other CommonJS loader) or server-side (in Node.js).

Using the jQuery plugin, client-side

Syntax:

$ (target).render (source, data)
  • data is an optional object who's content will be available as pseudo-global variables for javascript code running in the template.
  • The target selector supports any CSS selector.
  • There are three syntaxes for the source expression, which allows selecting from three types of template sources. See below.
  • Minitemp compiles and caches the templates using the source expression as a cache key.

Rendering an external template

Specify the relative or absolute URL of the template file as the source argument.

Example
$ ('#targetElement').render ('fileUrl.ejs', data);

Rendering a template embedded in a DOM element

The source template expression supports only a single id (ex: '#id') or class (ex: '.class') CSS selector.

Example
$ ('#targetElement').render ('#sourceTemplate', data);

or

$ ('#targetElement').render ('.sourceTemplate', data);

Rendering a precompiled string template

To render a named template, specify the template name prefixed by @ as the source expression.

// On startup
minitemp.defineTemplate ('templateName', templateStr);
 
// Somewhere else
$ ('#targetElement').render ('@templateName', data);

Using minitemp without jQuery, client-side

Rendering a string template

var template = '<p>Hello <%=name %>, how are you?</p>';
var html = minitemp.render (template, data);
// Do something with the resulting html.

Warning: when directly rendering string templates, the resulting compiled templates are not cached, as there is no key to save/retrieve them from the cache. Therefore, performance will be lower.

Rendering an external template into a DOM element

minitemp.renderFile (url, data, function (err, html) {
    if (err) throw err;
    document.getElementById('target').innerHTML = html;
});

Rendering a template embedded in a DOM element into another DOM element

// On startup:
 
// Get the template's HTML.
var templateStr = document.getElementById('sourceTemplate').innerHTML;
 // Precompile the template.
minitemp.defineTemplate ('templateName', templateStr);
 
// Somewhere else:
 
// Render the template into a string.
var html = minitemp.renderTemplate('templateName', data);
// Inject the rendered HTML into a DOM element.
document.getElementById('target').innerHTML = html;

Loading external templates

Minitemp provides a load function, which you can use to load template files without using jQuery.

Example
minitemp.load (url, function (err, template)
{
  if (err) throw (err);
  else {
    // Do something with the template.
  }
});

This same function can also be used server-side. It either uses XMLHttpRequest on the browser or the Node.js API on the server.

Compiling templates

You can convert an HTML template into an optimized javascript function, which can be used for directly rendering the template.

var compiled = minitemp.compile (template);

To render it, call:

var html = compiled (data);

Using minitemp on the server, with Node.js

You can render templates into HTML strings, which can then be sent to the browser using your framework of choice (ex. Express).

Example using the Express 4 framework

app.route('/dogs')
 
  .get (function (req, res, next)
  {
    minitemp.renderFile ('dogs.ejs', data,
      function (err, html)
      {
        if (err) throw err;
        else res.send (html);
      });
  });
 

Rendering a string template

var template = '<p>Hello <%=name %>, how are you?</p>';
var html = minitemp.render (template, data);
// Send the resulting html to the browser.

Warning: when directly rendering string templates, the resulting compiled templates are not cached, as there is no key to save/retrieve them from the cache. Therefore, performance will be lower.

Rendering an external template

minitemp.renderFile (url, data, function (err, html) {
    if (err) handle_the_error();
    else do_something(); // Send the resulting html to the browser.
});

Rendering a precompiled template

// On startup:
 
 // Precompile the template.
minitemp.defineTemplate ('templateName', "<p>This is <%=name %>'s template</p>");
 
// Somewhere else:
 
// Render the template into a string.
var html = minitemp.renderTemplate('templateName', data);
// Send the resulting html to the browser.

Options

At any time, you may specify one or more options for configuring the minitemp engine.

minitemp.options (options);

Available options

open: String

Redefines the open tag character sequence. Defaults to <%.

close: String

Redefines the close tag character sequence. Defaults to %>.

context: Object

Properties of this object will be available as globals for code runnning in the template.
By setting the same context for multiple instances of MinTemp, you can share data or utility functions between them.

The utility API

Minitemp provides several utility functions that can be called inside your templates.

e (string)

Escapes an HTML fragment. Equivalent to <%= string =%>.

ea (string)

Escapes an HTML attribute value.
This is faster than e() and generates shorter strings, as it avoids some HTML encodings that are not needed for attributes.
Always use with the <%- %> raw output tags.

Example:
<div title="<%- ea(title) %>">Hello</div>

attr (name:string, value:any[, args:Array][, defaultValue:any])

@param {string} name        Attribute name.
@param {*}      value       Attribute value.
@param {Array}  args        Arguments to be injected into the attribute value replacing ? placeholders.
@param {*}      defaultVal  Value to be used when the value argument is empty.

Outputs a complete HTML attribute by specifying its name and its value. If the value is empty, the whole attribute won't be generated.

This also helps generating attributes with dynamic values by allowing a list of arguments to be injected into the attribute value.

Example:
<div <%- attr ('onclick', info && 'showDetail(?,?)', [id, price]) %>> Click me! </div>

showIf (condition:boolean)

If the condition expression is false, it hides the element where this expression lies by outputting a style="display:none" attribute.

Example:
<div <%- showIf (isSenior (my.age)) %> class="warning">You are old.</div>

dynalist (map:Object, separator:string)

@param {Object.<string,boolean>} map        A map of strings to boolean values.
@param {string=}                 separator  List items separator; defaults to a space.

Concatenates the names of each key in a given object who's value is truthy.
It can be used, for instance, to generate dynamic CSS class lists.

Example:
<div class="header <%= dynalist ({active: isActive, first: isFirst()})">

Macros

Macros are JavaScript language extensions that are available only inside templates.

Minitemp comes with a single built-in macro: the for (var in array) statement.

Unlike the standard javascript for (v in a) statement, when this macro is used inside a template, it is converted into an array looping construct like this:

for (var i = 0, m = a.length, v; v = a[i], i < m; ++i)

The generated code is very similar to what you would have to manually write on each loop of your templates, but the macro is shorter and more readable.

This macro implements functionality similar to the proposed ES6 for (v of a) statement, but it uses current javascript syntax. This way, an IDE (like WebStorm with the EJS plugin) doesn't display any syntax error warnings on those statements.

Macros limitations

Macros can only be applied to javascript source code inside tagged blocks. They cannot span multiple blocks or target the HTML code.

Defining your own macros

Each macro can be defined by an array containg a regular expression and a substitution expression.

To add your own application-specific macros to the minitemp engine, push them into the macros property.

Example:

An example macro for an ifSet (variable) stringExp construct, which outputs a string only if the specified variable is defined:

minitemp.macros.push([/ifSet\s*\((.*?)\)(.*)/g, 'typeof $1 != "undefined" ? $2 : ""']);
var output = minitemp.render ('<p><%= ifSet(name) 'Hello ' + name %></p>', {name: 'John'});

More examples

Additional examples are available on the tests folder.

How to build the library

If you make changes to the source code, you may rebuild the minified javascript file using Grunt.

You'll need to checkout the full source code (not the one installed via Bower) and you must have NodeJS and Grunt installed.

To install the build tool, on the project folder type npm install on the command line.

Now, whenever you need to rebuild the library, simply type grunt.

History

Version Date Description
v2.1.1 2014-04-01 Universal Module Loader support.
v2.0.0 2014-03-31 jQuery plugin. API-breaking changes.
v1.0.0 2014-03-23 Initial release.

License

The MIT License (MIT)

Copyright (c) 2014 Cláudio Silva

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Readme

Keywords

none

Package Sidebar

Install

npm i minitemp

Weekly Downloads

0

Version

2.1.1

License

MIT

Last publish

Collaborators

  • claudio-silva