SkillAgentSearch skills...

Tempo

Tempo is an easy, intuitive JavaScript rendering engine that enables you to craft data templates in pure HTML.

Install / Use

/learn @twigkit/Tempo
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

Tempo 2.0

Tempo is an easy, intuitive JavaScript rendering engine that enables you to craft data templates in pure HTML.

Why use Tempo?

  • Clear separation of concerns: no HTML in your JavaScript files, and no JavaScript in your HTML
  • Makes working with AJAX/JSON content a piece of cake
  • Works in Safari, Chrome, FireFox, Opera, and Internet Explorer 6+

Key Features

  • Itty-bitty footprint, lightning-fast rendering!
  • No dependencies - Use with or without jQuery
  • Supports partial, nested and conditional templates
  • Support for pre-processing, filter and formatting functions and safe attribute setters
  • Variable injection for inline JavaScript expressions
  • Degrades gracefully if JavaScript is not enabled
  • Configurable syntax for greater compatibility

Quick start

1. Include the Tempo script

<script src="js/tempo.js" type="text/javascript"></script>
<script>Tempo.prepare("tweets").render(data);</script>

2. Compose the data template inline in HTML

<ol id="tweets">
    <li data-template>
        <img src="default.png" data-src="{{profile_image_url}}" />
        <h3>{{from_user}}</h3>
        <p>{{text}}<span>, {{created_at|date 'HH:mm on EEEE'}}</span></p>
    </li>
    <li data-template-fallback>Sorry, JavaScript required!</li>
</ol>

3. Booyah! You're done!

Usage

You only need to include one little script:

<script src="js/tempo.js" type="text/javascript"></script>

Data

Tempo takes information encoded as JSON and renders it according to an HTML template. Below is a sample array of JSON data. Tempo can also iterate members of an associative array (object).

var data = [
    {'name':{'first':'Leonard','last':'Marx'},'nickname':'Chico','born':'March 21, 1887','actor': true,'solo_endeavours':[{'title':'Papa Romani'}]},
    {'name':{'first':'Adolph','last':'Marx'},'nickname':'Harpo','born':'November 23, 1888','actor':true,'solo_endeavours':[{'title':'Too Many Kisses','rating':'favourite'},{'title':'Stage Door Canteen'}]},
    {'name':{'first':'Julius Henry','last':'Marx'},'nickname':'Groucho','born': 'October 2, 1890','actor':true,'solo_endeavours':[{'title':'Copacabana'},{'title':'Mr. Music','rating':'favourite'},{'title':'Double Dynamite'}]},
    {'name':{'first':'Milton','last':'Marx'},'nickname':'Gummo','born':'October 23, 1892'},
    {'name':{'first':'Herbert','last':'Marx'},'nickname':'Zeppo','born':'February 25, 1901','actor':true,'solo_endeavours':[{'title':'A Kiss in the Dark'}]}
];

JavaScript

Tempo.prepare()

First you need to point Tempo at the container that contains the template elements:

var template = Tempo.prepare(element);

element

The ID of the HTML element (or the element itself) containing your data template. If you're using jQuery, you may pass in a jQuery object instead.

To initialize Tempo, run the prepare() function to scan an HTML container for data templates, cache them in memory, and remove the data template HTML elements from the page. Tempo.prepare(element) returns an instance of a renderer that knows how to layout the data you provide to it.

If the container does not contain a default (that is without conditions and not nested) data-template the entire contents of the container will be considered to represent the template.

template.render()

template.render(data);

The Tempo.prepare() function returns an instance of a template ready for rendering. Once the JSON data is available, run the render(data) function to add the data to the page.

data

The JSON data to be rendered - either an array or an object in which case the members are iterated and provided as key/value pairs.

template.append()

Renderer methods all return an instance of the renderer (a la fluent) so you can chain calls to it. The append(data) function will render the data you pass in and append it to the container.

Tempo.prepare('marx-brothers').render( data ).append( more_brothers );

template.prepend()

The prepend(data) function will render the data you pass in and insert it before others in the container.

Tempo.prepare('marx-brothers').render( data ).prepend( brothers_we_didnt_know_about );

template.clear()

The clear() function will empty the container, allowing you to e.g. render the data again.

Tempo.prepare('marx-brothers').render( data ).clear();

template.errors(errorHandler)

Tempo will attempt to deal with errors and failures silently but you can pass in your own handler for exceptions:

errorHandler

A function which will be called with the error object from the try/catch block.

Tempo.prepare('list').errors(function (err) {
    console.log('Whoa! something happened!');
    console.log(err);
}).render(data);

template.into(container)

The into(element) function will allow you to render the original template to one or more different containers specified. The method will return a new template on which you can call the other template methods such as render() or append().

container

The container to render the template to.

Render to different container:
Tempo.prepare('marx-brothers').into('alternative-container').render( data );
Reuse template for multiple different containers:
var template = Tempo.prepare('marx-brothers');
template.into('alternative-container').render( data_1 );
template.into('yet-another-alternative-container').render( data_2 );

HTML

data-template

Any tag with the data-template attribute will be treated as a template. For compliance the full (non-minimized) form is also supported: data-template="data-template".

{{field}}

Any field represented in the JSON data may be retrieved by referencing the field name inside double brackets.

<ol id="marx-brothers">
    <li data-template>{{nickname}} {{name.last}}</li>
</ol>

The example above would produce the following output:

1. Chico Marx
2. Harpo Marx
3. Groucho Marx
4. Gummo Marx
5. Zeppo Marx

Here's an example of a simple array of strings:

var data = [ 'Leonard Marx', 'Adolph Marx', 'Julius Henry Marx', 'Milton Marx', 'Herbert Marx' ];

You can reference the object being iterated with {{.}}:

<ol id="marx-brothers">
    <li data-template>{{.}}</li>
</ol>

If the JSON data represents an array of arrays (which can not be referenced by field/member name) for example:

var data = [ ['Leonard','Marx'], ['Adolph','Marx'], ['Julius Henry','Marx'], ['Milton','Marx'], ['Herbert','Marx'] ];

You can reference array elements with the following notation:

<ol id="marx-brothers">
    <li data-template>{{[0]}} {{[1]}}</li>
</ol>

Both examples would produce the following output:

1. Leonard Marx
2. Adolph Marx
3. Julius Henry Marx
4. Milton Marx
5. Herbert Marx

Using data from associative arrays (objects)

Normally data being iterated is represented as an array of objects. In some cases however the data is a series of objects in a map:

var data = {
    'leonard': 'Leonard Marx',
    'adolph': 'Adolph Marx',
    'julius': 'Julius Henry Marx',
    'milton': 'Milton Marx',
    'herbert': Herbert Marx'
};

In this case you can iterate all the elements using the data-from-map attribute where the key name can be accessed with {{key}} and the value object via {{value}}:

<ol id="list">
    <li data-template data-from-map>{{value}} - {{key | append '@marx.com'}}</li>
</ol>

Values are escaped by default

All values are escaped by default. To disable automatic escaping pass in the 'escape': false parameter:

Tempo.prepare('marx-brothers', {'escape': false}).render(data);

If you disable escaping you can control this at individual value level using the escape and encodeURI filters.

Nested data-templates

Data templates can even be nested within other data templates. Multiple nested templates are supported.

<li data-template>
    {{nickname}} {{name.last}}
    <ul>
        <li data-template-for="solo_endeavours">{{title}}</li>
    </ul>
</li>

The example above would produce the following output:

1. Chico Marx
	◦ Papa Romani
2. Harpo Marx
	◦ Too Many Kisses
	◦ Stage Door Canteen
3. Groucho Marx
	◦ Copacabana
	◦ Mr. Music
	◦ Double Dynamite
4. Gummo Marx
5. Zeppo Marx
	◦ A Kiss in the Dark

You can (recursively) refer to parent objects within a nested template using the _parent variable.

<li data-template-for="solo_endeavours">{{_parent.name.first}} acted in {{title}}</li>

Nested Templates as Partial Template Files

Tempo supports separating more complex nested templates in to master and partial template files. Partials templates are loaded on demand from the server and do require you to use the alternative asynchronous pattern:

JavaScript:
Tempo.prepare('marx-brothers', {}, function(template) {
   template.render(data);
});
Template:
<li data-template>
    {{name.first}} {{name.last}}
    <ol>
        <li data-template-for="solo_endeavours" data-template-file="partials/movie.html"></li>
    </ol>
</li>
Partial ('partials/movie.html'):
{{title}}

This would produce the same output as the example above:

1. Chico Marx
	◦ Papa Romani
2. Harpo Marx
	◦ Too Many Kisses
	◦ Stage Door Canteen
3. Groucho Marx
	◦ Copacabana
	◦ Mr. Music
	◦ Double Dynamite
4. Gummo Marx
5. Zeppo Marx
	◦ A Kiss in the Dark
	

Conditional Templates

Tempo provides boolean and value-based conditionals, as well as the ability to define multiple data templates per container (the first matching template wins).

<ul id="marx-brothers3">
    <li data-template data-if-nickname="Groucho"">{{nickname}} (aka {{name.first}}) was grumpy!</li>
    <li data-template data-if-actor>{{name.first}}, nicknamed '<i>{{nickname}} {{name.last}}</i>' was born on {{born}}</li>

    <!-- Default template -->
    <li data-template>{{name.first}} {{name.last}} was not in any movies!</li>
</ul>

This example would pro

View on GitHub
GitHub Stars711
CategoryDevelopment
Updated12d ago
Forks73

Languages

JavaScript

Security Score

95/100

Audited on Mar 20, 2026

No findings