jQuery API

jQuery Plugin

.tmpl()

.tmpl( [data] [, options] ) Returns: jQuery

Description: Take the first element in the matched set and render its content as a template, using the specified data.

  • .tmpl( [data] [, options] )

    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.

The .tmpl() method is designed for chaining with .appendTo, .prependTo, .insertAfter or .insertBefore as in the following example.

Example:

$( "#myTemplate" ).tmpl( myData ).appendTo( "#target" );

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 return value is a jQuery collection of elements made up of the rendered template items (one for each data item in the array). If the template contains only one top-level element, then there will be one element for each data item in the array.

To insert the rendered template items into the HTML DOM, the returned jQuery collection should not be inserted directly into the DOM, but should be chained with .appendTo, .prependTo, .insertAfter or .insertBefore, as in the example above:

See also jQuery.tmpl().

The following example shows how to use .tmpl() to render local data using an inline template.

<ul id="movieList"></ul>

<script id="movieTemplate" type="text/x-jquery-tmpl">
    <li><b>${Name}</b> (${ReleaseYear})</li>
</script>

<script type="text/javascript">
    var movies = [
        { Name: "The Red Violin", ReleaseYear: "1998" },
        { Name: "Eyes Wide Shut", ReleaseYear: "1999" },
        { Name: "The Inheritance", ReleaseYear: "1976" }
    ];

    // Render the template with the movies data and insert
    // the rendered HTML under the "movieList" element
    $( "#movieTemplate" ).tmpl( movies )
        .appendTo( "#movieList" );
</script>

Using Remote Data

Typically the data is not local and is instead obtained using an Ajax request to a remote service or page, as in the following example:

$.ajax({
    dataType: "jsonp",
    url: moviesServiceUrl,
    jsonp: "$callback",
    success: showMovies
});

// Within the callback, use .tmpl() to render the data.
function showMovies( data ) {
    // Render the template with the "movies" data and insert
    // the rendered HTML under the 'movieList' element
    $( "#movieTemplate" ).tmpl( data )
        .appendTo( "#movieList" );
}

The Container Element for the Template

You can get the markup for the template from inline markup in the page, or from a string (possibly computed, or obtained remotely). For an example of how to get the markup from a string, see jQuery.tmpl().

If a template is defined inline in the page, you can use $( selector ).tmpl( data ), where selector is a selector referencing the container element that wraps the markup. The container can be any element, such as a <div> element whose style attribute includes display:none. However, this can result in invalid HTML or lead to side effects as a result of the browser parsing the markup and loading it into the DOM. Therefore, a preferred approach is to use a script tag such as <script id="myContainer" type="text/x-jquery-tmpl"> to wrap the markup. For the browser, the content will then be treated simply as text.

Caching the Template

When a template is rendered, the markup is first converted into a compiled-template function. In the case of inline markup, calling $( "#myContainer" ).tmpl( myData ) automatically causes the compiled template to be cached. (The cached template is associated with the DOM element that wraps the markup, using the jQuery .data() feature).

For convenience, you can also use $( "#myContainer" ).template( name ) so that you can reference the cached template by name. (See .template() for examples).

Template Tags, Expressions, and Template Variables

Template tags such as the ${} tag can used within jQuery templates in addition to text and HTML markup to enable a number of scenarios such as composition of templates, iteration over hierarchical data, parameterization of template rendering, etc. Template tags can render content based on the values of data item fields or template variables such as $item (corresponding to the template item), as well as expressions and function calls. See the documentation topics for each template tag: ${}, {{each}}, {{if}}, {{else}}, {{html}}, {{tmpl}} and {{wrap}}.

The options Parameter, and Template Items

Each template item (the result of rendering a data item with the template) is associated with a tmplItem data structure, which can be accessed using jQuery.tmplItem() and .tmplItem(), or the $item template variable. Any fields or anonomyous methods passed in with the options parameter of .tmpl() will extend the tmplItem data structure, and so be available to the template as in the following example:

Code:
// Render the template with the movies data
$( "#movieTemplate" ).tmpl( movies,
    { 
        myValue: "somevalue",
        myMethod: function() { 
            return "something";
        } 
    } 
).appendTo( "#movieList" );

Template:
<script id="movieTemplate" type="text/x-jquery-tmpl"> 
    <li>
        Some content: ${$item.myMethod()}.<br/>
        More content: ${$item.myValue}.
    </li>
</script> 

Additional Notes:

  • Netflix recently changed the API that we use in the remote service example below. We are aware that this change breaks the demo and will work on an update as soon as we can.
  • A new template plugin fully supported by the jQuery Team is now being developed as part of jQuery UI. More details on the history of this decision can be found on the jQuery blog. Track progress and participate in the design on the jQuery UI Planning Wiki.

Examples:

Example: Render local data using .tmpl().

<!DOCTYPE html>
<html>
<head>
  <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"> 
    <li><b>${Name}</b> (${ReleaseYear})</li>
</tmpl>

<ul id="movieList"></ul>

<script>
var movies = [
    { Name: "The Red Violin", ReleaseYear: "1998" },
    { Name: "Eyes Wide Shut", ReleaseYear: "1999" },
    { Name: "The Inheritance", ReleaseYear: "1976" }
];

/* Render the template with the movies data and insert
   the rendered HTML under the "movieList" element */
$( "#movieTemplate" ).tmpl( movies )
    .appendTo( "#movieList" );
</script>

</body>
</html>

Demo:

Example: Render data from a remote service using .tmpl().

<!DOCTYPE html>
<html>
<head>
  <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"> 
    <li><b>${Name}</b> (${ReleaseYear})</li>
</tmpl>

<button id="cartoonsBtn">Cartoons</button>
<button id="dramaBtn">Drama</button>

<ul id="movieList"></ul>

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

$( "#cartoonsBtn" ).click( function() {
    getMovies( "Cartoons", 0, 6 );
});

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

</body>
</html>

Demo:

Support and Contributions

Need help with .tmpl() or have a question about it? Visit the jQuery Forum or the #jquery channel on irc.freenode.net.

Think you've discovered a jQuery bug related to .tmpl()? Report it to the jQuery core team.

Found a problem with this documentation? Report it to the jQuery API team.

* All fields are required
  • Barney Carroll

    Would be interesting to read a rationale explaining why and how this diverged from John Resig's tmpl function from mid-2008 (http://ejohn.org/blog/javascript-micro-templating/), which appears to be superior in most respects.

    A few aspects of significant difference don't seem to be for the better:
    • Replacement of the easily-legible, unambiguous <% %> syntax with the cluttered, confusing {{ }} (looks like an object wrapper) and ${ } (looks like a call to the jQuery object).
    • No more real Javascript. The original allowed unfettered Javascript use in the templates. Now apparently the only looping device is the ambiguous each, effectively forcing the developer to learn a limited, confusing new language. The notion of closing if else statements with {{/if}} when previously the existing Javascript language could be used, is another particularly unfortunate example.
    • The number of ways of handling invocation and recursion has increased substantially. Arguably, the extra range of options could be to the benefit of the tmpl framework, but it might be retorted that this simply adds a confusing selection of methods for achieving what could already be done with the original tmpl and a basic understanding of Javascript — whereas in comparison to other respects, the range of implementation methods has increased, it is not to any significant increase in power — essentially we now have more ways of doing not as much.

    The marked area of increase is in byte-size — 6007 minified compared to the original's (uncommented) 498. Is there a roadmap detailing what the aims were and are so we can get a better idea as to what's going on with this potentially fantastic plugin?

  • http://www.learningjquery.com/ Karl Swedberg
  • http://programmerforhire.com.au JohnM

    If you create the template on the fly you still have to wrap it in some discardable tags lest it strip the outermost element from your template. ie:

    $('<script><li>${txt}</li></script>').tmpl(items).appendTo(ul)

    • http://www.borismoore.com Boris Moore

      That corresponds to the spec:
      Take the first element in the matched set and render _its content_ as a template, using the specified data.

      A better way to create templates on the fly is to use jQuery.template, as in:
      $.template(“myTemplate”, “<li>${txt}</li>”);
      $.tmpl(“myTemplate”, data).appendTo(…);

  • Tang Biao

    There is a small error in the sample code of options parameter: “myMethod: function() {” missing out “: function”.

    • http://www.borismoore.com Boris Moore

      Thanks. Fixed.

  • Rich Goldman

    I have a concern with tmpl() and firebug. The error messages I'm encountering while developing are not helpful at all. Sometimes I see transient errors involving some tmpl function called “prntNde”. Are there plans to improve the error messaging somehow?

    • http://www.borismoore.com Boris Moore

      We are still in Beta. I hope error messages and exceptions will be better by the time we release.

  • Roel Kramer

    I created my own template tag and wrote a post about my experiences. The example might be handy for other developers wanting to create their own tags as well. There is no documentation about how to do this, so I tried to do my best. If there are any suggestions or errors please let me know. It can be found here:
    http://blog.sterkwebwerk.nl/20…/
    Within a few days I'll finish part 2, which is about writing tags with an open and close tag.

  • Roel Kramer

    I created my own template tag and wrote a post about my experiences. The example might be handy for other developers wanting to create their own tags as well. There is no documentation about how to do this, so I tried to do my best. If there are any suggestions or errors please let me know. It can be found here:
    http://blog.sterkwebwerk.nl/20…/
    Within a few days I'll finish part 2, which is about writing tags with an open and close tag.

  • Gediminas

    Moore, it would be beneficial if .appendTo could accept jQuery object – not only selector :)

    • http://www.borismoore.com Boris Moore

      That is a request for appendTo, so is not related to templates. But take a look at the doc for appendTo and you will see that it does accept a jQuery object.

  • Epik

    What if I need to replace a value inside double quote?
    For example:
    <a href='/Request/${IdRequest}'>Click here</a>
    The plugin seems not to manage that.

    • http://www.borismoore.com Boris Moore

      That should work fine.

  • http://openid-provider.appspot.com/anders.malmgren80 Anders

    I've used jquery templating in a new project. Its very nice, but one major feature im missing is the ability to connect data to a element for later retrieval.

    Something like
    <li ${this.user=”$item}” class=”user-item”>$(Fullname}</li>

    This would add a property on the LI element called user that holds the databind data

    You could also do ${this.name = $(Fullname} etc

    What do guys think?

  • jscheel

    The x-jquery-tmpl script technique is incredibly hacky, and has failed on several browsers in my experience.

    • http://www.borismoore.com Boris Moore

      Can you give details on which browsers it is failing?

      • jscheel

        Hmm, well, insert foot in mouth. I just wrote a simple test and everything seems to be working. Looked back and it seems that the person implementing my code was including additional items that were causing some conflicts with jquery. Please ignore, thanks!

  • JackSh

    Hi,

    I wish to apply effects when rendering a template :
    have each rendered instance of the template “fade in”, and let all such “fade in”s occur one after another with a very short time delay between each.

    Is that possible? … if so, how?