1KB lightweight, fast & powerful JavaScript templating engine with zero dependencies. Compatible with server-side environments like node.js, module loaders like RequireJS and all web browsers.

Overview

JavaScript Templates

Contents

Description

1KB lightweight, fast & powerful JavaScript templating engine with zero dependencies.
Compatible with server-side environments like Node.js, module loaders like RequireJS or webpack and all web browsers.

Usage

Client-side

Install the blueimp-tmpl package with NPM:

npm install blueimp-tmpl

Include the (minified) JavaScript Templates script in your HTML markup:

<script src="js/tmpl.min.js"></script>

Add a script section with type "text/x-tmpl", a unique id property and your template definition as content:

<script type="text/x-tmpl" id="tmpl-demo">
  <h3>{%=o.title%}</h3>
  <p>Released under the
  <a href="{%=o.license.url%}">{%=o.license.name%}</a>.</p>
  <h4>Features</h4>
  <ul>
  {% for (var i=0; i<o.features.length; i++) { %}
      <li>{%=o.features[i]%}</li>
  {% } %}
  </ul>
</script>

"o" (the lowercase letter) is a reference to the data parameter of the template function (see the API section on how to modify this identifier).

In your application code, create a JavaScript object to use as data for the template:

var data = {
  title: 'JavaScript Templates',
  license: {
    name: 'MIT license',
    url: 'https://opensource.org/licenses/MIT'
  },
  features: ['lightweight & fast', 'powerful', 'zero dependencies']
}

In a real application, this data could be the result of retrieving a JSON resource.

Render the result by calling the tmpl() method with the id of the template and the data object as arguments:

document.getElementById('result').innerHTML = tmpl('tmpl-demo', data)

Server-side

The following is an example how to use the JavaScript Templates engine on the server-side with Node.js.

Install the blueimp-tmpl package with NPM:

npm install blueimp-tmpl

Add a file template.html with the following content:

<!DOCTYPE HTML>
<title>{%=o.title%}</title>
<h3><a href="{%=o.url%}">{%=o.title%}</a></h3>
<h4>Features</h4>
<ul>
{% for (var i=0; i<o.features.length; i++) { %}
    <li>{%=o.features[i]%}</li>
{% } %}
</ul>

Add a file server.js with the following content:

require('http')
  .createServer(function (req, res) {
    var fs = require('fs'),
      // The tmpl module exports the tmpl() function:
      tmpl = require('./tmpl'),
      // Use the following version if you installed the package with npm:
      // tmpl = require("blueimp-tmpl"),
      // Sample data:
      data = {
        title: 'JavaScript Templates',
        url: 'https://github.com/blueimp/JavaScript-Templates',
        features: ['lightweight & fast', 'powerful', 'zero dependencies']
      }
    // Override the template loading method:
    tmpl.load = function (id) {
      var filename = id + '.html'
      console.log('Loading ' + filename)
      return fs.readFileSync(filename, 'utf8')
    }
    res.writeHead(200, { 'Content-Type': 'text/x-tmpl' })
    // Render the content:
    res.end(tmpl('template', data))
  })
  .listen(8080, 'localhost')
console.log('Server running at http://localhost:8080/')

Run the application with the following command:

node server.js

Requirements

The JavaScript Templates script has zero dependencies.

API

tmpl() function

The tmpl() function is added to the global window object and can be called as global function:

var result = tmpl('tmpl-demo', data)

The tmpl() function can be called with the id of a template, or with a template string:

var result = tmpl('<h3>{%=o.title%}</h3>', data)

If called without second argument, tmpl() returns a reusable template function:

var func = tmpl('<h3>{%=o.title%}</h3>')
document.getElementById('result').innerHTML = func(data)

Templates cache

Templates loaded by id are cached in the map tmpl.cache:

var func = tmpl('tmpl-demo'), // Loads and parses the template
  cached = typeof tmpl.cache['tmpl-demo'] === 'function', // true
  result = tmpl('tmpl-demo', data) // Uses cached template function

tmpl.cache['tmpl-demo'] = null
result = tmpl('tmpl-demo', data) // Loads and parses the template again

Output encoding

The method tmpl.encode is used to escape HTML special characters in the template output:

var output = tmpl.encode('<>&"\'\x00') // Renders "&lt;&gt;&amp;&quot;&#39;"

tmpl.encode makes use of the regular expression tmpl.encReg and the encoding map tmpl.encMap to match and replace special characters, which can be modified to change the behavior of the output encoding.
Strings matched by the regular expression, but not found in the encoding map are removed from the output. This allows for example to automatically trim input values (removing whitespace from the start and end of the string):

tmpl.encReg = /(^\s+)|(\s+$)|[<>&"'\x00]/g
var output = tmpl.encode('    Banana!    ') // Renders "Banana" (without whitespace)

Local helper variables

The local variables available inside the templates are the following:

  • o: The data object given as parameter to the template function (see the next section on how to modify the parameter name).
  • tmpl: A reference to the tmpl function object.
  • _s: The string for the rendered result content.
  • _e: A reference to the tmpl.encode method.
  • print: Helper function to add content to the rendered result string.
  • include: Helper function to include the return value of a different template in the result.

To introduce additional local helper variables, the string tmpl.helper can be extended. The following adds a convenience function for console.log and a streaming function, that streams the template rendering result back to the callback argument (note the comma at the beginning of each variable declaration):

tmpl.helper +=
  ',log=function(){console.log.apply(console, arguments)}' +
  ",st='',stream=function(cb){var l=st.length;st=_s;cb( _s.slice(l));}"

Those new helper functions could be used to stream the template contents to the console output:

<script type="text/x-tmpl" id="tmpl-demo">
  <h3>{%=o.title%}</h3>
  {% stream(log); %}
  <p>Released under the
  <a href="{%=o.license.url%}">{%=o.license.name%}</a>.</p>
  {% stream(log); %}
  <h4>Features</h4>
  <ul>
  {% stream(log); %}
  {% for (var i=0; i<o.features.length; i++) { %}
      <li>{%=o.features[i]%}</li>
      {% stream(log); %}
  {% } %}
  </ul>
  {% stream(log); %}
</script>

Template function argument

The generated template functions accept one argument, which is the data object given to the tmpl(id, data) function. This argument is available inside the template definitions as parameter o (the lowercase letter).

The argument name can be modified by overriding tmpl.arg:

tmpl.arg = 'p'

// Renders "<h3>JavaScript Templates</h3>":
var result = tmpl('<h3>{%=p.title%}</h3>', { title: 'JavaScript Templates' })

Template parsing

The template contents are matched and replaced using the regular expression tmpl.regexp and the replacement function tmpl.func. The replacement function operates based on the parenthesized submatch strings.

To use different tags for the template syntax, override tmpl.regexp with a modified regular expression, by exchanging all occurrences of "{%" and "%}", e.g. with "[%" and "%]":

tmpl.regexp = /([\s'\\])(?!(?:[^[]|\[(?!%))*%\])|(?:\[%(=|#)([\s\S]+?)%\])|(\[%)|(%\])/g

By default, the plugin preserves whitespace (newlines, carriage returns, tabs and spaces). To strip unnecessary whitespace, you can override the tmpl.func function, e.g. with the following code:

var originalFunc = tmpl.func
tmpl.func = function (s, p1, p2, p3, p4, p5, offset, str) {
  if (p1 && /\s/.test(p1)) {
    if (
      !offset ||
      /\s/.test(str.charAt(offset - 1)) ||
      /^\s+$/g.test(str.slice(offset))
    ) {
      return ''
    }
    return ' '
  }
  return originalFunc.apply(tmpl, arguments)
}

Templates syntax

Interpolation

Print variable with HTML special characters escaped:

<h3>{%=o.title%}</h3>

Print variable without escaping:

<h3>{%#o.user_id%}</h3>

Print output of function calls:

<a href="{%=encodeURI(o.url)%}">Website</a>

Use dot notation to print nested properties:

<strong>{%=o.author.name%}</strong>

Evaluation

Use print(str) to add escaped content to the output:

<span>Year: {% var d=new Date(); print(d.getFullYear()); %}</span>

Use print(str, true) to add unescaped content to the output:

<span>{% print("Fast &amp; powerful", true); %}</span>

Use include(str, obj) to include content from a different template:

<div>
  {% include('tmpl-link', {name: "Website", url: "https://example.org"}); %}
</div>

If else condition:

{% if (o.author.url) { %}
<a href="{%=encodeURI(o.author.url)%}">{%=o.author.name%}</a>
{% } else { %}
<em>No author url.</em>
{% } %}

For loop:

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

Compiled templates

The JavaScript Templates project comes with a compilation script, that allows you to compile your templates into JavaScript code and combine them with a minimal Templates runtime into one combined JavaScript file.

The compilation script is built for Node.js.
To use it, first install the JavaScript Templates project via NPM:

npm install blueimp-tmpl

This will put the executable tmpl.js into the folder node_modules/.bin. It will also make it available on your PATH if you install the package globally (by adding the -g flag to the install command).

The tmpl.js executable accepts the paths to one or multiple template files as command line arguments and prints the generated JavaScript code to the console output. The following command line shows you how to store the generated code in a new JavaScript file that can be included in your project:

tmpl.js index.html > tmpl.js

The files given as command line arguments to tmpl.js can either be pure template files or HTML documents with embedded template script sections. For the pure template files, the file names (without extension) serve as template ids.
The generated file can be included in your project as a replacement for the original tmpl.js runtime. It provides you with the same API and provides a tmpl(id, data) function that accepts the id of one of your templates as first and a data object as optional second parameter.

Tests

The JavaScript Templates project comes with Unit Tests.
There are two different ways to run the tests:

  • Open test/index.html in your browser or
  • run npm test in the Terminal in the root path of the repository package.

The first one tests the browser integration, the second one the Node.js integration.

License

The JavaScript Templates script is released under the MIT license.

Comments
  • How to use two independent instances of the Templates function

    How to use two independent instances of the Templates function

    Original title: "Remove from the global window ?"

    Hey Sebastian,

    Any chance that you can remove tmpl from the global window and add to to its own window to avoid conflicts ?

    Any reason not to do this ?

    Thanks

    opened by andyscott12 11
  • Uncaught Error: Syntax error, unrecognized expression:

    Uncaught Error: Syntax error, unrecognized expression:

    If you will upgrade to jQuery 1.9 and use custom templates, you will face this error: Uncaught Error: Syntax error, unrecognized expression:

    This causes line: 59:template = tplContainer.html(); Change to: template = $($.parseHTML(tplContainer.html()));

    http://bugs.jquery.com/ticket/13223

    opened by VaclovasV 6
  • Compiled template problem

    Compiled template problem

    According to documentation, compiled my templates to external file: tmpl.js templates/test/test.html > tmpl-templates.min.js

    Documentation wrote: The generated file can be included in your project as a replacement for the original tmpl.js runtime. But this is not true - if I include only tmpl-templates.min.js, in same html page write new template with , I can't use tmpl("new1"), only templates, described in test.html. What I'm doing wrong? Including plain tmpl.min.js with tmpl-templates.min.js does not help. I think, compiled version must fill the templates cache and leave other template behavior unchanged.

    opened by gincius 3
  • Added support for requireJs 'define'.

    Added support for requireJs 'define'.

    Hello,

    While working with the script I got the following error:

    Uncaught TypeError: Cannot read property 'splice' of undefined almond.min.js:216
    define almond.min.js:216
    (anonymous function) tmpl.js:44
    (anonymous function) tmpl.js:47
    .............
    (anonymous function) tmpl.js:10
    

    As it turned out, Almond's/requireJs's define() function takes 3 params: function (name,deps,callback)

    Javascript-Templates's current implementation only passes the callback. Thus define() tries to use it as a name(first argument). To fix the problem, we need to pass all three parameters, just like I propose in my pull request:

    window.define('tmpl', [], function() { // name, deps, callback
    

    Hopefully, this will fix problem not only for me, but for the other people who uses the library. Wish you good luck!

    Also, before seding pull request I wanted to run tests(yeah, this change is relatively small but still...) - to check everything's going well. README file doesn't contain info/command for this. It would be easier if you included this.

    Thanks.

    opened by akhabibullina 3
  • problems with jquery 1.9

    problems with jquery 1.9

    There is a smaller problem with jquery 1.9 in that the new jquery does not allow whitespace to be "first" in the html string, ie $("

    test

    ") is allowed but $("

    test

    ") is not allowed.

    this makes it harder to have "pretty" templates in your code when using it with jquery. for example

    will fail when used with $(tmpl("test"))

    since the template result will start with "whitespace" characrters (return, space, etc)

    at the moment the workaround for me is to use the $.parseHTML function so that I now get

    $($.parseHTML(tmpl("test")))

    Is there any way to make it "trim" the whitespace at the beginning (and at the end) automaticly?

    opened by christian-andersson 3
  • script tag that contains template is in another context

    script tag that contains template is in another context

    Hi, i'm using the code

    tmpl("tmpl-demo", {})
    

    but my code is in iframe and my script tag that have a template content, is out this iframe, i.e., in my parent!

    How can i take the element #tmpl-demo?

    opened by giolvani 3
  • using custom functions within JavaScript Templates

    using custom functions within JavaScript Templates

    In my template I'd like to format my dates and have them update periodically.

    I saw the following in the documentation:

    <span>Year: {% var d=new Date(); print(d.getFullYear()); %}</span>

    my question is how to use my own custom function, nicetime(), in my template instead of getFullYear().

    here's what i'd like to work, but doesn't:

    <span>Year: {% var d=nicetime(); print(d); %}</span>

    here's what nicetime() looks like:

    function nicetime(){ var time = new Date(), comment_date = setInterval(function() { var time2 = time_since(time.getTime()/1000); return time2; // 1 second ago, then 2 seconds ago, and so on... }, 1000); }

    time_since() formats the code in Facebook-style: "2 seconds ago...".

    any thoughts would be greatly appreciated?

    opened by tim-peterson 3
  • CDATA

    CDATA

    <script id="foobar" type="text/html">
      //<![CDATA[
        code / template
      //]]>
    </script>
    

    if you use it without CDATA it will not validate as xhtml. I my self use html5 where it doesn't matter, but some people do care about that, and so does the framework I want to use it with. Is there a chance this script will support the use of templates with // in it? (So far the template output is messed up, it doesn't output anything between start and the first variable in the template)

    opened by Zauberfisch 3
  • Travis-CI build support

    Travis-CI build support

    Hi,

    It's a fantastic plugin.

    Travis-CI ensure that all of the commits (as well as the pull requests) are automatically checked. Since your project has already everything setup for automatic tests. You can visit the fork in my profile and check the "Build Passing" image.

    This is the least I can do to improve it :-)

    Have a nice day...

    opened by MythicAngel 2
  • Exposing license information according to bower format

    Exposing license information according to bower format

    license field should contain String or Array of Strings. See: http://bower.io/docs/creating-packages/

    Current format doesn't work with libraries that inspect and generate information about all the libraries used in the project (e.g. grunt-license-bower).

    opened by mkotsur 2
  • Return empty string instead of

    Return empty string instead of "undefined" on non-existent variables

    On line 69 (first line of tmpl.encode) I added this super simple patch to return an empty string instead of the string "undefined" when a specific value is not passed to the function.

    if (!s) return '';
    

    Figured I'd at least put it out here in case others are looking for the same thing, and maybe it's something you want to include (or know a more correct way for).

    Thanks for a super simple-to-use, slim and awesome lib.

    opened by Mark-H 2
  • Avoid using new Function()

    Avoid using new Function()

    The new Function(...), user here: https://github.com/blueimp/JavaScript-Templates/blob/master/js/tmpl.js#L24

    is a bad practice, and disabled by default if using Content Security Policy (see here)

    Can this be replaced? Otherwise who uses CSP must add unsafe-eval to use this library, allowing potential secutiry vulnerabilities.

    opened by fmonts 6
Owner
Sebastian Tschan
🍌banana banana banana
Sebastian Tschan
Asynchronous Javascript templating for the browser and server

Dust.js Asynchronous Javascript templating for the browser and server. This fork is maintained by LinkedIn. Install NPM Important: We recommend that y

LinkedIn 2.9k Dec 31, 2022
Asynchronous Javascript templating for the browser and server

Dust.js Asynchronous Javascript templating for the browser and server. This fork is maintained by LinkedIn. Install NPM Important: We recommend that y

LinkedIn 2.9k Dec 31, 2022
The fastest + concise javascript template engine for nodejs and browsers. Partials, custom delimiters and more.

doT Created in search of the fastest and concise JavaScript templating function with emphasis on performance under V8 and nodejs. It shows great perfo

Laura Doktorova 4.9k Dec 31, 2022
Minimal templating with {{mustaches}} in JavaScript

mustache.js - Logic-less {{mustache}} templates with JavaScript What could be more logical awesome than no logic at all? mustache.js is a zero-depende

Jan Lehnardt 15.7k Jan 7, 2023
A tiny javascript templating framework in ~400 bytes gzipped

t.js A tiny javascript templating framework in ~400 bytes gzipped t.js is a simple solution to interpolating values in an html string for insertion in

Jason Mooberry 823 Dec 29, 2022
handlebars.js 8.8 4.4 L3 JavaScript An extension to the Mustache templating language.

Handlebars.js Handlebars provides the power necessary to let you build semantic templates effectively with no frustration. Handlebars is largely compa

The Handlebars Templating Language 16.9k Jan 5, 2023
handlebars.js - An extension to the Mustache templating language.

Handlebars.js Handlebars provides the power necessary to let you build semantic templates effectively with no frustration. Handlebars is largely compa

The Handlebars Templating Language 16.9k Jan 5, 2023
A compiler for the Mustache templating language

Hogan.js - A mustache compiler. Hogan.js is a compiler for the Mustache templating language. For information on Mustache, see the manpage and the spec

Twitter 5.1k Jan 2, 2023
Embedded JS template engine for Node, Deno, and the browser. Lighweight, fast, and pluggable. Written in TypeScript

eta (η) Documentation - Chat - RunKit Demo - Playground Summary Eta is a lightweight and blazing fast embedded JS templating engine that works inside

Eta 682 Dec 29, 2022
A Zero config CLI to quick-start your web projects.

Quick-strapper A Zero-config cli to help you bootstrap web projects with best templates. Quick-strapper Usage Templates Commands Usage You can start u

Sidharth Rathi 3 Jun 14, 2022
eXtensible Template Engine lib for node and the browser

xtemplate High Speed, eXtensible Template Engine lib on browser and nodejs. support async control, inheritance, include, logic expression, custom func

xtemplate 553 Nov 21, 2022
Pug – robust, elegant, feature rich template engine for Node.js

Pug Full documentation is at pugjs.org Pug is a high-performance template engine heavily influenced by Haml and implemented with JavaScript for Node.j

Pug 21.1k Dec 30, 2022
Convert a simple HTML syntax into tables compatible with Foundation for Emails.

Inky Inky is an HTML-based templating language that converts simple HTML into complex, responsive email-ready HTML. Designed for Foundation for Emails

Foundation 652 Dec 22, 2022
Take a swig of the best template engine for JavaScript.

NOT MAINTAINED Fork and use at your own risk. Swig Swig is an awesome, Django/Jinja-like template engine for node.js. Features Available for node.js a

Paul Armstrong 3.1k Jan 4, 2023
Semi-embedded JS template engine that supports helpers, filters, partials, and template inheritance. 4KB minzipped, written in TypeScript ⛺

squirrelly Documentation - Chat - RunKit Demo - Playground Summary Squirrelly is a modern, configurable, and blazing fast template engine implemented

Squirrelly 451 Jan 2, 2023
✨ A multipurpose discord bot, that can help you manage & entertain your server.

Helper Helper is a mutil purpose discord bot that is designed to bring management & entertainment to your server. ( This bot is inspired by WickBot &

Saige 4 Sep 13, 2022
Variation-template - Variation is a PSD template that is covered into a web template using HTML5, CSS3, Bootstrapv4.6, JavaScript.

Variation Template Design Variation is a PSD website template. In this project this template is designed with HTML. Deployment This site is deployed a

Bipronath Saha 1 Jan 1, 2022
This is a simple ticket system bot using discord.js v13 and node.js v17. It works with buttons and slashcommands.

Ticket-bot This is an simple ticket system bot using discord.js v13. If you find an error or need support, go to my discord server and open a ticket >

Cristhian 14 Jan 2, 2023
An example project using Node.js to run some common tasks including directory backup

All code from this tutorial as a complete package is available in this repository. If you find this tutorial helpful, please share it with your friend

Alex 11 Sep 28, 2022