jQuery Templates: Template Tags

With the basics of templates out of the way, it’s time to look at some of the further features available with the Template plugin. Simply mapping data to markup in a consistent way is useful, but several other features are available that allow for greater control.

1. Adding Simple Logic to Your Templates with {{if}} {{else}}

{{if}} and {{else}} provide conditional inclusion of content in templates. It renders content between the {{if}} and closing {{/if}} tag only if a provided value is not null. {{else}} indicates alternative content to be rendered if the provided expression is false. The following example illustrates using {{if}} and {{else}} to conditionally include a thumbnail image. If the thumbnail isn’t set in the data source, a default image will be included.

<!DOCTYPE html>

<html>

<head>

<meta charset=”utf-8″>

</head>

<body>

<div id=”main”> </div>

<script src=”http://code.jquery.com/jquery-1.7.1.min.js”></script>

<script src=” //ajax.aspnetcdn.com/ajax/jquery.templates/beta1/jquery.tmpl.min.js”>

</script>

<script>

$(function(){

var comics = [{

imgSrc : “cover1.jpg”,

title : “Captain Templates”,

year : “2010”,

number : “1”

},

{

imgSrc : “cover2.jpg”,

title : “Captain Templates”,

year : “2011”,

number : “2”

},

{

title : “Captain Templates”,

year : “2012”,

number : “3”

}];

$( “#comics” ).tmpl(comics).appendTo(“#main”);

}

);

</script>

<script id=”comics” type=”text/x-jquery-tmpl”>

<div class=”comic”>

{{if imgSrc}}

<img src=”${imgSrc}” />

{{else}}

<img src=”default.jpg” />

{{/if}}

<div class=”details”>

<div class=”title”>

<h3>${title}</h3>

</div>

<div class=”year”>

${year}

</div>

<div class=”number”>

${number}

</div>

</div>

</div>

</script>

</body>

</html>

Code snippet is from if.txt

Applying the template to the data produces the output shown in Figure 11-2

2. Iterate Over Data Objects with {{each}}

Like $.each(), {{each}} is used to iterate over a data array. It renders content between the opening and closing template tags once for each data item. As the following code sample shows, the data structure exposes an array of “themes” for each comic. The associated inline template uses {{each}} to list out a series of one or more themes for every template element. Each theme is wrapped in a list item.

<!DOCTYPE html>

<html>

<head>

<meta charset=”utf-8″>

</head>

<body>

<div id=”main”> </div>

<script src=”http://code.jquery.com/jquery-1.7.1.min.js”></script>

<script src=” //ajax.aspnetcdn.com/ajax/jquery.templates/beta1/jquery.tmpl.min.js”>

</script>

<script>

$(function(){

var comics = [{

imgSrc : “cover1.jpg”,

title : “Captain Templates”,

themes :  [

“code reuse” ,

“separation of content and behavior” ,

“template tags”

],

year : “2010”,

number : “1”

},

{

imgSrc : “cover2.jpg”,

title : “Captain Templates”,

themes :  [

“code reuse” ,

“moustaches” ,

“templating for fun and profit”

],

year : “2011”,

number : “2”

},

{

imgSrc : “cover3.jpg”,

title : “Captain Templates”,

themes :  [ “threes” ],

year : “2012”,

number : “3”

}];

$( “#comics” ).tmpl( comics ).appendTo( “#main” );

}

);

</script>

<script id=”comics” type=”text/x-jquery-tmpl”>

<div class=”comic”><img src=”${imgSrc}” />

<div class=”details”>

<div class=”title”>

<h3>${title}</h3>

</div>

<div class=”year”>

<strong>Year:</strong> ${year}

</div>

<div class=”number”>

<strong>Issue Number:</strong> ${number}

</div>

<div class=”themes”>

<strong>Themes</strong>

<ul>

{{each themes}}

<li>${$value}</li>

{{/each}}

</ul>

</div>

</div>

</div>

</script>

</body>

</html>

Code snippet is from each.txt

Additionally, {{each}} exposes an index, which allows for the integration of a counter in the template itself. The following variation of the previous template illustrates this:

<!DOCTYPE html>

<html>

<head>

<meta charset=”utf-8″>

</head>

<body>

<div id=”main”> </div>

<script src=”http://code.jquery.com/jquery-1.7.1.min.js”></script>

<script src=” //ajax.aspnetcdn.com/ajax/jquery.templates/beta1/jquery.tmpl.min.js”>

</script>

<script>

$(function(){

var comics = [{

imgSrc : “cover1.jpg”,

title : “Captain Templates”,

themes : [

“code reuse” ,

“separation of content and behavior” ,

“template tags”

],

year : “2010”,

number : “1”

},

{

imgSrc : “cover2.jpg”,

title : “Captain Templates”,

themes : [

“code reuse” ,

“moustaches” ,

“templating for fun and profit”

],

year : “2011”,

number : “2”

},

{

imgSrc : “cover3.jpg”,

title : “Captain Templates”,

themes :  [ “threes” ],

year : “2012”,

number : “3”

}];

$( “#comicsIndex” ).tmpl( comics ).appendTo( “#main” );

}

);

</script>

<script id=”comicsIndex” type=”text/x-jquery-tmpl”>

<div class=”comic”><img src=”${imgSrc}” />

<div class=”details”>

<div class=”title”>

<h3>${title}</h3>

</div>

<div class=”year”>

<strong>Year:</strong> ${year}

</div>

<div class=”number”>

<strong>Issue Number:</strong> ${number}

</div>

<div class=”themes”>

<strong>Themes</strong>

{{each themes}}

<strong>${$index + 1}</strong>. ${$value}

{{/each}}

</div>

</div>

</div>

</script>

</body>

</html>

Code snippet is from each-index.txt

3. Nesting Templates with {{tmpl}}

The {{tmpl}} template tag enables you to nest templates. This allows for much greater code reuse. If, for example, you had a common structure for displaying thumbnails and titles across several separate templates, you could define the thumbnail and title as one template and reference it wherever needed.

Following are the three inline templates. The first, headerTemplate, defines a common header used in the other two templates, comicsConcise and comicsExtended.

<!DOCTYPE html>

<html>

<head>

<meta charset=”utf-8″>

</head>

<body>

<div id=”main”> </div>

<script src=”http://code.jquery.com/jquery-1.7.1.min.js”></script>

<script src=” //ajax.aspnetcdn.com/ajax/jquery.templates/beta1/jquery.tmpl.min.js”>

</script>

<script>

$(function(){

var comics = [{

imgSrc : “cover1.jpg”,

title : “Captain Templates”,

themes : [

“code reuse” ,

“separation of content and behavior” ,

“template tags”

],

year : “2010”,

number : “1”

},

{

imgSrc : “cover2.jpg”,

title : “Captain Templates”,

themes : [

“code reuse” ,

“moustaches” ,

“templating for fun and profit”

],

year : “2011”,

number : “2”

},

{

imgSrc : “cover3.jpg”,

title : “Captain Templates”,

themes : [ “threes” ],

year : “2012”,

number : “3”

}];

$( “#comicsConcise” ).tmpl( comics ).appendTo( “#main” );

$( “#comicsExtended” ).tmpl( comics ).appendTo( “#main” );

}

);

</script>

<script id=”headerTemplate” type=”text/x-jquery-tmpl”>

<header>

<h1>${title}</h1>

<img src=”${imgSrc}” />

</header>

</script>

<script id=”comicsConcise” type=”text/x-jquery-tmpl”>

<section class=”comic”>

{{tmpl “#headerTemplate”}}

<div class=”details”>

<div class=”year”>

<strong>Year:</strong> ${year}

</div>

<div class=”number”>

<strong>Issue Number:</strong> ${number}

</div>

</div>

</section>

</script>

<script id=”comicsExtended” type=”text/x-jquery-tmpl”>

<section class=”comic extended”>

{{tmpl “#headerTemplate”}}

<div class=”details”>

<div class=”year”>

<strong>Year:</strong> ${year}

</div>

<div class=”number”>

<strong>Issue Number:</strong> ${number}

</div>

<div class=”themes”>

<strong>Themes</strong>

<ul>

{{each themes}}

<li>${$value}</li>

{{/each}}

</ul>

</div>

</div>

</section>

</script>

</body>

</html>

Code snippet is from tmpl.txt

Taking advantage of this ability to piece templates together with smaller chunks of code makes your code much more maintainable. Identify the common elements, break them out into their own templates, and then you’re able to update a single template instead of poking around multiple templates looking for markup to change.

4. Embed HTML Into Your Templates with {{html}}

Occasionally, entire sections of HTML are included in data returned from a web service. Using the {{html}} template tag enables you to insert this prerendered HTML directly into your templates. Without {{html}}, then text like <a href=’http://jquery.com’>jquery.com</a> would appear literally, e.g. &gta href=…, and thus would not have the intended effect.

In the following code, the data includes a description field that contains HTML text. Areas where HTML is to be output directly are bracketed by {{html}} template tags.

<!DOCTYPE html>

<html>

<head>

<meta charset=”utf-8″>

</head>

<body>

<div id=”main”> </div>

<script src=”http://code.jquery.com/jquery-1.7.1.min.js”></script>

<script src=” //ajax.aspnetcdn.com/ajax/jquery.templates/beta1/jquery.tmpl.min.js”>

</script>

<script>

$(function(){

var comics = [{

imgSrc : “cover1.jpg”,

title : “Captain Templates”,

themes : [

“code reuse” ,

“separation of content and behavior” ,

“template tags”

],

year : “2010”,

number : “1”,

description : “<p>In this thrilling origin issue Captain

Templates saves the day by using templates instead of a bunch of

<strong>awkward</strong> string concatenation</p>”

},

{

imgSrc : “cover2.jpg”,

title : “Captain Templates”,

themes :  [

“code reuse” ,

“moustaches” ,

“templating for fun and profit”

],

year : “2011”,

number : “2”,

description : “<p>In battling his <em>arch nemesis</em>

<strong>Doctor Plus Sign</strong> Captain Templates falls into a coma.

</p><p>A thrilling issue with a cliffhanger ending</p>”

},

{

imgSrc : “cover3.jpg”,

title : “Captain Templates”,

themes : [ “threes” ],

year : “2012”,

number : “3”,

description : “<p>Captain Templates awakens from his coma and

defeats the evil <strong>Doctor Plus Sign</strong></p>”

}];

$( “#comics” ).tmpl( comics ).appendTo( “#main” );

}

);

</script>

<script id=”comics” type=”text/x-jquery-tmpl”>

<section class=”comic”>

<header>

<img src=”${imgSrc}” />

<h3>${title}</h3>

</header>

<div class=”details”>

<div class=”year”>

<strong>Year:</strong> ${year}

</div>

<div class=”number”>

<strong>Issue Number:</strong> ${number}

</div>

<div class=”description”>

{{html description}}

</div>

</div>

</section>

</script>

</body>

</html>

Code snippet is from html.txt

Source: Otero Cesar, Rob Larsen (2012), Professional jQuery, John Wiley & Sons, Inc

Leave a Reply

Your email address will not be published. Required fields are marked *