jQuery & jQuery UI Documentation

jQuery & jQuery UI

jQuery Plugin

{{tmpl}} Template Tag

{{tmpl( [data], [options] ) template}}

Description: Used for composition of templates. Renders one or more nested template items within the rendered output of the parent template.

  • version added: 1.4.3{{tmpl( [data], [options] ) template}}

    templateThe HTML markup or text to use as a template.

    dataThe data to render. This can be any JavaScript type, including Array or Object.

    optionsAn optional map of user-defined key-value pairs. Extends the tmplItem data structure, available to the template during rendering.

This documentation topic concerns the jQuery Templates plugin (jquery-tmpl), which can be downloaded from: http://github.com/jquery/jquery-tmpl.

Note: For information about how to render templates, see .tmpl() and jQuery.tmpl().

Template Tags

Template tags such as the {{tmpl}} tag can be used within jQuery templates in addition to text and HTML markup, in order to enable a number of scenarios such as composition of templates, iteration over hierarchical data, parameterization of template rendering, etc.

Other available tags include: ${}, {{each}}, {{if}}, {{else}}, {{html}} and {{wrap}}. User-defined template tags can also be specified, by extending the jQuery.tmpl.tag map.

Using the {{tmpl}} Template Tag

The following example shows how to use {{tmpl}} to render a nested template.

<script id="movieTemplate" type="text/x-jquery-tmpl"> 
    {{tmpl "#titleTemplate"}}
    <tr class="detail"><td>Director: ${Director}</td></tr>
</script>

<script id="titleTemplate" type="text/x-jquery-tmpl"> 
    <tr class="title"><td>${Name}</td></tr>
</script>

The template parameter can be any of the following:

  • A string containing markup.
  • An HTML element (or jQuery object that wraps an element) whose content is to be used as the template.
  • A string corresponding to the name of a named template (see jQuery.template() and .template()).
  • A compiled-template function (see jQuery.template() and .template()).

If data is an array, the template is rendered once for each data item in the array. If data is an object, or if the data parameter is missing or null, a single template item is rendered.

The following example shows how to iterate over hierarchical data, by passing a data parameter to the a nested {{tmpl}} tag.

Templates:
<script id="movieTemplate" type="text/x-jquery-tmpl"> 
    <tr>
        <td>${Name}</td>
        <td>{{tmpl(Languages) "#languageTemplate"}}</td>
    </tr>
</script>

<script id="languageTemplate" type="text/x-jquery-tmpl"> 
    <em>${Name}</em>
</script>
Data:
var movies = [
    { Name: "Meet Joe Black", Languages: ["English", "French"] },
    { Name: "The Mighty", Languages: ["English"] },
    { Name: "City Hunter", Languages: ["Mandarin", "Cantonese"] }
];

Recursive Nested {{tmpl}} Tags

A template may contain a {{tmpl}} or {{wrap}} tag referencing the same template. The following example uses a recursive template to create a tree view:

Templates:
<script id="folderTmpl" type="text/x-jquery-tmpl">
    <li class="toggle">
        <span class="expand">${expanderSymbol($item)}</span>
        <span>${name}</span>
    </li>
    {{if expanded}}
        <li>
            <ul>{{tmpl(getFolderItems($item)) "#itemTmpl"}}</ul>
            <ul>{{tmpl(getSubFolders($item)) "#folderTmpl"}}</ul>
        </li>
    {{/if}}
</script>

<script id="itemTmpl" type="text/x-jquery-tmpl">
    <li class="folderItem">${name}</li>
</script>
Data:
// Hierarchy of named folders 
var folders = {
    name: "Samples",
    folders: [
        { name: "API", folders: [
            { name: ".tmpl()"}
        ]},
        { name: "Template markup", folders: [
            { name: "Tags", folders: [
                { name: "{{wrap}}"}
            ]},
        ]},
    ]
};

// Array for the folder items. Each item can show up in one or more folders
var samples = [
    { name: "Template in script block", 
        folders: [ ".tmpl()" ], 
        description: "Rendering a template declared in script block" },
    { name: "Tab View", 
        folders: [ "{{wrap}}", ".tmpl()" ], 
        description: "A tab view, using {{wrap}}" }
];

Examples:

Example: Using {{tmpl}} to render a nested template.

<!DOCTYPE html>
<html>
<head>
  <style>
table { border-collapse:collapse; border:2px solid blue; margin:5px; background-color:#f8f8f8; }
table tr { border:1px solid blue; } table td { padding:2px; }
.title { border-bottom:none; } .detail { border-top:none; }
</style>
  <script src="http://code.jquery.com/jquery-latest.min.js"></script>
  <script src="http://ajax.microsoft.com/ajax/jquery.templates/beta1/jquery.tmpl.min.js"></script>
</head>
<body>
  
<tmpl id="movieTemplate" type="text/x-jquery-tmpl"> 
    {{tmpl "#titleTemplate"}}
    <tr class="detail"><td>Director: ${Director}</td></tr>
</tmpl>

<tmpl id="titleTemplate" type="text/x-jquery-tmpl"> 
    <tr class="title"><td>${Name}</td></tr>
</tmpl>

<table><tbody id="movieList"></tbody></table>

<script>
var movies = [
    { Name: "The Red Violin", Director: "François Girard" },
    { Name: "Eyes Wide Shut", Director: "Stanley Kubrick" },
    { Name: "The Inheritance", Director: "Mauro Bolognini" }
];

/* Render the template with the movies data */
$( "#movieTemplate" ).tmpl( movies ).appendTo( "#movieList" );
</script>

</body>
</html>

Example: Using {{tmpl}} to render hierarchical data.

<!DOCTYPE html>
<html>
<head>
  <style>
table {float:left;clear:right;border-collapse:collapse;width:370px;background-color:#f8f8f8;margin:4px;} table td {border:1px solid blue;padding:3px;}
table th {font-weight:bold;border:2px solid blue;padding:1px;} table tbody {border:2px solid blue;} button {float:left;margin:4px;width:70px;}
</style>
  <script src="http://code.jquery.com/jquery-latest.min.js"></script>
  <script src="http://ajax.microsoft.com/ajax/jquery.templates/beta1/jquery.tmpl.min.js"></script>
</head>
<body>
  
<tmpl id="movieTemplate" type="text/x-jquery-tmpl"> 
    <tr>
        <td>${Name}</td>
        <td>{{tmpl(Languages.results) "#languageTemplate"}}</td>
    </tr>
</tmpl>

<tmpl id="languageTemplate" type="text/x-jquery-tmpl"> 
    <em>${Name} </em>
</tmpl>

<table><tbody><tr><th>Title</th><th>Languages</th></tr></tbody>
<tbody id="movieList"></tbody></table>
<button id="foreignBtn">Foreign</button>
<button id="dramaBtn">Drama</button>

<script>
function getMovies( genre, skip, top ) {
    $.ajax({
        dataType: "jsonp",
        url: "http://odata.netflix.com/Catalog/Genres('" + genre
            + "')/Titles?$format=json&$expand=Languages&$skip="
            + skip + "&$top=" + top,
        jsonp: "$callback",
        success: function( data ) {
            /* Get the movies array from the data */
            var movies = data.d.results;

            /* Remove current set of movie template items */
            $( "#movieList" ).empty();
            
            /* Render the template with the movies data and insert
               the rendered HTML under the "movieList" element */
            $( "#movieTemplate" ).tmpl( movies )
                .appendTo( "#movieList" );
        }
    });
}

$( "#foreignBtn" ).click( function() {
    getMovies( "Foreign", 0, 4 );
});

$( "#dramaBtn" ).click( function() {
    getMovies( "Drama", 0, 4 );
});
</script>

</body>
</html>

Example: Using the options parameter of the {{tmpl}} tag to provide a showLanguage method.

<!DOCTYPE html>
<html>
<head>
  <style>
table {float:left;clear:right;border-collapse:collapse;width:370px;background-color:#f8f8f8;margin:4px;} table td {border:1px solid blue;padding:3px;}
table th {font-weight:bold;border:2px solid blue;padding:1px;} table tbody {border:2px solid blue;} button {float:left;margin:4px;width:70px;}
</style>
  <script src="http://code.jquery.com/jquery-latest.min.js"></script>
  <script src="http://ajax.microsoft.com/ajax/jquery.templates/beta1/jquery.tmpl.min.js"></script>
</head>
<body>
  
<tmpl id="movieTemplate" type="text/x-jquery-tmpl"> 
    <tr>
        <td>${Name}</td>
        <td>{{tmpl(Languages.results, $item.languageOptions) "#languageTemplate"}}</td>
    </tr>
</tmpl>

<tmpl id="languageTemplate" type="text/x-jquery-tmpl"> 
    <em>${$item.showLanguage(Name)} </em>
</tmpl>

<table><tbody><tr><th>Title</th><th>Languages</th></tr></tbody>
<tbody id="movieList"></tbody></table>
<button id="foreignBtn">Foreign</button>
<button id="dramaBtn">Drama</button>

<script>
function getMovies( genre, skip, top ) {
    $.ajax({
        dataType: "jsonp",
        url: "http://odata.netflix.com/Catalog/Genres('" + genre
            + "')/Titles?$format=json&$expand=Languages&$skip="
            + skip + "&$top=" + top,
        jsonp: "$callback",
        success: function( data ) {
            /* Get the movies array from the data */
            var movies = data.d.results;

            /* Remove current set of movie template items */
            $( "#movieList" ).empty();

            /* Render the template items for each movie.
               Pass in the languageOptions map which will be used as
               options parameter on the nested "languageTemplate" template.
               The 'showLanguage' method will be called by the nested template. */
            $( "#movieTemplate" ).tmpl( movies, {
                languageOptions: {
                    showLanguage: function showLanguage( name ) {
                        return name.toUpperCase();
                    }
                }
            }).appendTo( "#movieList" );
        }
    });
}

$( "#foreignBtn" ).click( function() {
    getMovies( "Foreign", 0, 4 );
});

$( "#dramaBtn" ).click( function() {
    getMovies( "Drama", 0, 4 );
});
</script>

</body>
</html>

Example: A tree view, using recursive nested {{tmpl}} tags.

<!DOCTYPE html>
<html>
<head>
  <style>
.treeView li li {margin-left:18px;} .expand {vertical-align:middle;margin-right:7px;display:inline-block;border:1px solid #555;text-align:center;height:12px;width:12px;line-height:11px;background-color:#f8f8f8;color:Blue;} 
.treeView, .treeView ul {padding:0;margin:0;} .treeView li {margin-left:8px;list-style-type:none;padding:2px;cursor:pointer;} .treeView li.folderItem {color:Blue;text-decoration:underline;font-style:italic;margin-bottom:4px;}
</style>
  <script src="http://code.jquery.com/jquery-latest.min.js"></script>
  <script src="http://ajax.microsoft.com/ajax/jquery.templates/beta1/jquery.tmpl.min.js"></script>
</head>
<body>
  
<tmpl id="folderTmpl" type="text/x-jquery-tmpl">
    <li class="toggle">
        <span class="expand">${expanderSymbol($item)}</span>
        <span>${name}</span>
    </li>
    {{if expanded}}
        <li>
            <ul>{{tmpl(getFolderItems($item)) "#itemTmpl"}}</ul>
            <ul>{{tmpl(getSubFolders($item)) "#folderTmpl"}}</ul>
        </li>
    {{/if}}
</tmpl>

<tmpl id="itemTmpl" type="text/x-jquery-tmpl">
    <li class="folderItem">${name}</li>
</tmpl>

<ul id="samplesList" class="treeView"><li></li></ul>

<script>
 /* Hierarchy of named folders */ 
var folders = {
    name: "Samples",
    folders: [
        { name: "API", folders: [
            { name: ".tmpl()"}
        ]},
        { name: "Template markup", folders: [
            { name: "Tags", folders: [
                { name: "{{wrap}}"}
            ]},
        ]},
    ]
};

/* Array for the folder items. Each item can show up in one or more folders */
var samples = [
    { name: "Template in script block", 
        folders: [ ".tmpl()" ], 
        description: "Rendering a template declared in script block" },
    { name: "Template as string", 
        folders: [ ".tmpl()" ], 
        description:"Rendering a template passed as a string" },
    { name: "Render remote data", 
        folders: [ "API" ], 
        description: "Rendering remote data using templates" },
    { name: "Tab View", 
        folders: [ "{{wrap}}", ".tmpl()" ], 
        description: "A tab view, using {{wrap}}" }
];

/* Declare the functions for getting the items and subfolders, etc. 
   These could be simple global functions. 
   (Here we are adding them to the window object, which is equivalent). */
$.extend( window, { 
    getFolderItems: function( tmplItem ) {
        return $.map( samples, function( sample ) {
            return $.inArray( tmplItem.data.name, sample.folders ) > -1 ? sample : null;
        });
    }, 
    getSubFolders: function( tmplItem ) {
        return tmplItem.data.folders || [];
    }, 
    expanderSymbol: function( tmplItem ) {
        return tmplItem.data.expanded ? "-" : "+";
    }
});

$( "#folderTmpl" ).tmpl( folders ).appendTo( "#samplesList" );

$( "#samplesList" )
    .delegate( ".toggle", "click", function() {
        /* Toggle expanded property on data, then update rendering */
        var tmplItem = $.tmplItem( this );
        tmplItem.data.expanded = !tmplItem.data.expanded;
        tmplItem.update();
    })
    .delegate( ".folderItem", "click", function() {
        alert( $.tmplItem( this ).data.description );
    });
</script>

</body>
</html>