13

The documentation for jquery.tmpl uses .appendTo to insert the template into the DOM during the rendering process:

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

I am attempting to convert an existing app from another templating engine, and my code needs to render a template into a string first before it is added to the DOM. Is this possible? How would that be done?

Adam Lassek
  • 35,156
  • 14
  • 91
  • 107

6 Answers6

17

The answers here didn't help me, however Adam's reply set me on the right track: any jQuery wrapped element has a .html() method.

var output = $( "#infoWindowTemplate" ).tmpl( city_data ).html()

or if you need text...

var output = $( "#infoWindowTemplate" ).tmpl( city_data ).text()

but please take note, that the outermost(root) element of the template is skipped, so you should make your templates look something like this:

  <script id='infoWindowTemplate' type='text/x-jquery-tmpl'> 
    <div class='city_info'>
      <h1 class='title'><a href="${link}">${name}</a></h1>
      <p class='meta'>${count} offers</p>
    </div>
  </script> 

or just use the jQuery outerHtml plugin ( http://darlesson.com/jquery/outerhtml/ ) and replace .html() with .outerHTML()

galileoMonkey
  • 715
  • 6
  • 12
  • Now that we have [Handlebars](http://www.handlebarsjs.com/) for compiled Mustache templates I really don't see a compelling reason to use jQuery.tmpl – Adam Lassek Jul 25 '11 at 21:47
  • 1
    Could you give a reason why Handlebars/Mustache templates are more appropriate than jquery.tmpl? They seem very similar to me. – hofnarwillie May 24 '12 at 22:18
  • 1
    +1 for 'please take note, that the outermost(root) element of the template is skipped'. Saved my day. – BaBu Jul 05 '13 at 08:37
13

You could do it by just putting the result in a temporary container and taking the innerHTML of it, like this:

var str = $("<div />").append($.tmpl(myTemplate, myData)).html();
Nick Craver
  • 623,446
  • 136
  • 1,297
  • 1,155
  • This almost worked. needs to be: var div = $("
    "); $.tmpl(myTemplate, myData).appendTo(div); var content = div.html(); vote up for leading in the right direction.
    – hofnarwillie May 24 '12 at 23:41
7

jQuery.tmpl returns an HTMLElement wrapped in a jQuery object, which could be used in the same way as rendered strings were in the old template system.

var $template = $('#template'),
    html = $.tmpl($template, data).get();

I suspect that this might actually be faster than regular strings, but I don't have any profiling data for this yet.


Update

I did some basic profiling between Mustache.js and jQuery.tmpl, and the stats do not look good.

I started with 1,000 preloaded records and generated templates for them several times, averaging the results.

Mustache.js: 1783ms
jQuery.tmpl: 2243ms

I might wait until jQuery.tmpl closes that gap before switching.

Adam Lassek
  • 35,156
  • 14
  • 91
  • 107
5

jQuery Templating provides $.template() (see description in source code) - it returns array of strings after evaluating cached template with your data. I am writing from scratch (and from experiments in Chrome's console), but you'll get the whole idea.

  1. Create and cache a named template function

    $("template-selector").template("template-name");
    
  2. Get your template function and invoke it with your data

    var tmpl = $.template("template-name"); // template function
    var strings = tmpl($, {data: {<your data here>}}); // array of strings
    var output = strings.join(''); // single string
    
Victor
  • 3,669
  • 3
  • 37
  • 42
  • Pretty sure this wasn't true when I asked the question, so thanks for the update. – Adam Lassek Jul 26 '13 at 05:23
  • https://github.com/BorisMoore/jquery-tmpl/commits/master/jquery.tmpl.js - at the Aug 09 2010 it was renamed from `templates` to `template`, so it was true in the latest version at the time you asked your question, and it was available under `$.templates()` even earlier, actually after https://github.com/BorisMoore/jquery-tmpl/commit/f2eab62ad2e796f375ece518b85824edeb40c980 at May 07 2010 – Victor Jul 26 '13 at 08:01
0

You can prepare template data like this

var tmplData = {link:"your link",name:"yourname",count:5};
$("#idofelementwhereuwanttoappend").append($("#infoWindowTemplate").tmpl(tmpldata));

This idofelementwhereuwanttoappend is id where your template data will be rendered.

Gryu
  • 2,102
  • 2
  • 16
  • 29
mukut
  • 130
  • 3
  • 3
  • You missed the entire point of the question. I wanted to combine rendered templates together in code _before_ doing DOM operations. – Adam Lassek Feb 27 '13 at 22:32
0

This works correctly

    var s = $.tmpl(url, dataContext).get()[0].data;

I was wrong, above example works only if returned is somethig other that html. In case of html I use

    var s = $.tmpl(url, dataContext).get()[0].outerHTML

EDIT: After some digging I discovered diffrences between Chrome and FF (above examples works in Chrome).

Finally I found cross browser working method, lets assume that we like to build a tag. So we template will look like

    <a href='${url}'>${text}</a>

them simplest way to get resul as a string is to wrap template inside any tag and then use .html() function

    var t = '<div><a href='${url}'>${text}</a></div>'
    var d = {url: 'stackoverflow.com', text: 'best site'};
    var html = $.tmpl(s, d).get()[0];
    html = $(html).html();  // trick is here
pma_
  • 810
  • 1
  • 8
  • 9