Handlebars

Problem

items = [{url:'/products/', text:'Products'},
         {url:'/home/', text:'Home'},
         {url:'/contact/', text:'Contact'}];


$.each(items, function (index, item) {

    var myHtml =  Template(item);
    $('#myContainer').append(myHtml);

});


var Template = function (item) {

    var myHtml = '<div>';
    myHtml    += '<a href="' + item.url + '">' + item.text + '</a>';
    myHtml    += '</div>';
  
    return myHtml;
};
items = [{url:'/products/', text:'Products'},
         {url:'/home/', text:'Home'},
         {url:'/contact/', text:'Contact'}];

$.each(items, function (index, item) {

    var myHtml =  Template(item);
    $('#myContainer').append(myHtml);

});


var Template = function (item) {

    var $myDiv  = $('<div></div>');
    var $myLink = $('<a></a>', { href:item.url, text:item.text});
    $myLink.appendTo($myDiv);

    return $myDiv;
};

in JavaScript (jQuery) Way...

What if...

items = [{url:'/products/', text:'Products'},
         {url:'/home/', text:'Home'},
         {url:'/contact/', text:'Contact'}];

$.each(items, function (index, item) {

    var myHtml =  Template(item);
    $('#myContainer').append(myHtml);

});


var Template = function (item) {

    var myHtml = 
        <div>
           <a href="item.url"> item.text </a>
        </div>
    
    return myHtml;
};
<script src="handlebars.js"></script>

<script id="my-template" type="text/x-handlebars-template">

        <div>
           <a href="{{item.url}}"> {{item.text}} </a>
        </div>

</script>
<script>

    var source   = $("#my-template").html();
    var myTemplate = Handlebars.compile(source);

</script>

How Handlebars do

1. create Template by HTML.

2. compile template by Handlebars.

<script id="my-template" type="text/x-handlebars-template">

        <div>
           <a href="{{url}}"> {{text}} </a>
        </div>

</script>
items = [{url:'/products/', text:'Products'},
         {url:'/home/', text:'Home'},
         {url:'/contact/', text:'Contact'}];


    var source   = $("#my-template").html();
    var myTemplate = Handlebars.compile(source);


$.each(items, function (index, item) {

    var myHtml =  myTemplate(item);
    $('#myContainer').append(myHtml);

});
<script id="my-template" type="text/x-handlebars-template">

        <div>
           <a href="{{url}}"> {{text}} </a>
        </div>

</script>

// Past Way 1.

    var myHtml = '<div>';
    myHtml    += '<a href="' + item.url + '">' + item.text + '</a>';
    myHtml    += '</div>';
  

// Past Way 2.

    var $myDiv  = $('<div></div>');
    var $myLink = $('<a></a>', { href:item.url, text:item.text});
    $myLink.appendTo($myDiv);

Compare

Case: Product Recommendation

  <div class="recommendedBlcok CompleteBlcok">
    <a name="Recommended" id="Recommended"></a>
    <h2 class="title-block fullBlock">Recommended for You</h2>
    <div class="recommendedContent carouselBannerSingle Carousel-w960" id="recommendedContentID">
      <ul>
        <li>
          <div class="recommendedContent-BG">
            <div class="recommendedContent-img">
              <img src="images/model-product.jpg">
            </div>
            <a href="#" target="_blank">AdvancedTCA</a>
            <p>Blades are designed in unison with the leading silicon suppliers...</p>
          </div>
        </li>
        <li>
          <div class="recommendedContent-BG">
            <div class="recommendedContent-img">
              <img src="images/model-product.jpg">
            </div>
            <a href="#" target="_blank">AdvancedTCA</a>
            <p>Advantech's AdvatncedTCA(ATCA) Blades are designed in unison with the leading silicon suppliers...</p>
          </div>
        </li>
        <li>
          <div class="recommendedContent-BG">
            <div class="recommendedContent-img">
              <img src="images/model-product.jpg">
            </div>
            <a href="#" target="_blank">AdvancedTCA</a>
            <p>Advantech's designed in unison with the leading silicon suppliers...</p>
          </div>
        </li>
        <li class="on4">
          <div class="recommendedContent-BG">
            <div class="recommendedContent-img">
              <img src="images/model-product.jpg">
            </div>
            <a href="#" target="_blank">AdvancedTCA</a>
            <p>Advantech's Blades are designed in unison with the leading silicon suppliers...</p>
          </div>
        </li>
      </ul>
    </div><!--recommendedContent-pad end-->

$.each(items, function (index, item) {
    innerRecThinkPower(item);
});


var innerRecThinkPower = function (item) {
    var itemHtml = '<li>';
    itemHtml += '   <div class="recommendedContent-BG">';
    itemHtml += '       <div class="recommendedContent-img" onclick="recommClickThinkPower(\'' + item.mainCate + '\', \'' + item.midCate + '\', \'' + item.endCate + '\', \'' + item.itemId + '\')">';
    itemHtml += '           <img src="' + item.imgUrl + '" alt="' + item.itemName.toUpperCase() + '">';
    itemHtml += '       </div>';
    itemHtml += '       <a href="' + item.itemUrl + '" target="_blank" onclick="recommClickThinkPower(\'' + item.mainCate + '\', \'' + item.midCate + '\', \'' + item.endCate + '\', \'' + item.itemId + '\')">' + item.itemName.toUpperCase() + '</a>';
    itemHtml += '       <p>' + item.modelDesc + '</p>';
    itemHtml += '   </div>';
    itemHtml += '</li>';

    $('.recommended-list', '#div_recommendation').append(itemHtml);
};

Before:

Case: Product Recommendation

    var innerRecThinkPower = function (item) {
        var source = $('#thinkpower-template').html(),
            template = Handlebars.compile(source),
            html = template(item);

        $('.recommended-list', '#div_recommendation').append(html);
    };

After:

<script id="thinkpower-template" type="text/x-handlebars-template">

    <li>
        <div class="recommendedContent-BG">
            <div class="recommendedContent-img" onclick="recommClickThinkPower('{{mainCate}}', '{{midCate}}', '{{endCate}}', '{{itemId}}')">
                <img src="{{imgUrl}}" alt="{{itemName}}">
            </div>
            <a href="{{itemUrl}}" target="_blank" onclick="recommClickThinkPower('{{mainCate}}', '{{midCate}}', '{{endCate}}', '{{itemId}}')">{{itemName}}</a>
            <p>{{{modelDesc}}}</p>
        </div>
    </li>

</script>

Case: Product Recommendation

Why handlebars? why not others...

  • ​jquery-tmpl.js

  • pure.js

  • jsrender.js

  • mustache.js

  • ... ... ... 

useful Helper

<!-- each -->
<ul id="comments">
  {{#each comments}}
      <li>{{description}}</li>
  {{/each}}
</ul>


<!-- if else -->
{{#if isActive}}
  <img src="star.gif" alt="Active">
{{else}}
  <img src="cry.gif" alt="Inactive">
{{/if}}


<!-- comment -->
<div class="entry">
  {{!-- only output author name if an author exists --}}
  {{! This comment will not be in the output }}
</div>

Feature. 1

Feature. 2

Handlebars is one of Node.js MVC View Template. 
( such as 
Razor in .NET MVC )

<html>
    <head>
	<title>Handlebars</title>
	{{{_sections.head}}}
    </head>
    <body>
	{{{body}}}
	{{{_sections.jquery}}}
    </body>
</html>
_Layout.htndlebars
{{#section 'head'}}
    <meta name="robots" content="noindex">
{{/section}}


<h1>Test Page</h1>
<p>We're test</p>


{{#section 'jquery'}}
<script>
    $('document').ready(function(){
        $('h1').html('jquery works');
    });
</script>
{{/section}}
home.htndlebars

Feature. 3

  • not jQuery dependency.
    but work well with jQuery.
  • Handlebars has been designed to work in any ECMAScript 3 environment.
    ( means IE6+ , but recommend IE9+)

Feature. 4

Similar Angular Template Pattern ??
They all love {{ }}

    
<ul>
    <li ng-repeat="item in items">{{item.country}}: {{item.goals}}</li>
</ul>
    
<ul>
    {{each items}}
        <li>{{country}}: {{goals}}</li>
    {{/each}}    
</ul>
  • Handlebars
  • Angular

Conclusion

  • easy to use js-library.
     
  • HTML friendly,  JS friendly.
     
  • Both Front-end and Back-end library.

Handlebars

By Jayson Chiang

Handlebars

  • 673