BOOSTING THE 

CLIENT-SIDE EVEN MORE WITH

 
by Alysson Ferreira @ Avenue Code
aferreira@avenuecode.com

Jan 20th, 2014

AGENDA


  • Motivation
    • Clientside templating
    • Thick Clients
    • Thick Clients vs Thick Servers
  • Handlebars.js
    • Definition
    • Why Handlebars?
    • How it works
    ______________________________________________
     Boosting the client-side even more with Handlebars

AGENDA


  • Handlebars Overview
    • The 3 Main Parts of Handlebars Templating
    • Syntax
    • Built-in Helpers
    • Custom Helpers
      • Custom Function Helpers
      • Custom Block Helpers
______________________________________________
 Boosting the client-side even more with Handlebars

pre-requisites




- Javascript: Intermediate level

- HTML: Intermediate level

______________________________________________
 Boosting the client-side even more with Handlebars




"My site is living in 2001. I have a pantry full of ajax powered spaghetti, and basically everything is a new page refresh. How can I made it slick?"

______________________________________________
 Boosting the client-side even more with Handlebars

Client Side Templating


    What is client side templating?


  • Generating HTML in the Browser

  • Generally used alongside with client side frameworks such as Backbone or Ember
______________________________________________
 Boosting the client-side even more with Handlebars

Thick client


  • What is it?
    • 'A computer (client) in client–server architecture that typically provides rich functionality independent of the central server.'

  • In other words, it removes some requirements from thick servers.

______________________________________________
 Boosting the client-side even more with Handlebars

Thick client Flow


  • Server sends Client templates + 'application code'.
  • Application code initializes the View.
  • As user interacts with the View, JSON data is transferred between client and server.
  • Application code applies templates to the data to update the view.

______________________________________________
 Boosting the client-side even more with Handlebars

why use thick clients?





Because there are problems with Thick Servers.

THICK Servers VS THICK CLIENTS

  • Server may be overkill.

    • Often have a gigantic piece of software to implement an application.
    • A lot of overhead due to Content Management System just to display some HTML pages.
    • Doesn't take advantage of the browser capabilities.
______________________________________________
 Boosting the client-side even more with Handlebars

THICK CLIENTS benefits


  • Infrastructure

  • Dynamic content can be expensive

  • Caching

______________________________________________
 Boosting the client-side even more with Handlebars


THICK CLIENTS BENEFITS


  • Thick servers works under non-optimal
    user experience.

  • Why?
    • Response times
      • 0.1 sec: Instantaneous
      • 1 sec: Sticky
      • 10 sec: What am I doing with my life?!
______________________________________________
 Boosting the client-side even more with Handlebars

MORE THICK CLIENTS Upsides


  • Avoids page reloads

  • Avoids inefficient architecture

  • Better separation of concerns

______________________________________________
 Boosting the client-side even more with Handlebars

MORE THICK CLIENTS Upsides


  • Avoids coupling

  • Avoids ugly clientside code

  • "Good architecture allows future features."
    - Yehuda Katz

______________________________________________
 Boosting the client-side even more with Handlebars

client side Templating BENEFITS


  • Avoids HTML generation in JS
  • Readable
  • Maintainable
  • Usable
  • Decoupled to the server
______________________________________________
 Boosting the client-side even more with Handlebars

Handlebars.JS


  • Contributed by Yehuda Kaltz
  • Logicless
  • Superset of Mustache
  • Powerful & extensible
  • Fast
______________________________________________
 Boosting the client-side even more with Handlebars

DEFINItion




  • Handlebars.js is a client-side templating engine for JS.

  • Handlebars.js has a compiler built with JS that takes any Handlebars template and compiles them to a JS function.



______________________________________________
 Boosting the client-side even more with Handlebars

how it works





______________________________________________
 Boosting the client-side even more  with Handlebars

when TO use it?


  • Frequent updates to the view, either due to data changes on the server or on the client.
  • You have multiple parts of your system dependant on your data from the server, and you want all the parts to process the same data.
  • Your application has much interactivity and is very responsive.
  • Your application is a single-page app with multiple views.
  • You don't want JS code to contain HTML markup.

______________________________________________
 Boosting the client-side even more with Handlebars

WHy handlebars ?


  • One of the most advanced, feature-rich and popular among all JS template engines (Mustache, Underscore, EJS, Dust.JS, etc)

  • Most active community.

  • Used on cutting edge and promising client side frameworks: Meteor.js, Derby.js and Ember.js.
    Super easy to be used with Backbone.
______________________________________________
 Boosting the client-side even more with Handlebars

  Handlebars essentials


  • To use Handlebars, first you link to the Handlebars.js file in the head block of your HTML page, just like you do for jQuery or any .js files.
______________________________________________
 Boosting the client-side even more with Handlebars

  Expressions


  • A simple expression is written like this:
      {{ content }}      
  • Or like this, in the case of Handlebars block expressions:
      <div> Name: {{ customerName }} </div>
    
______________________________________________
 Boosting the client-side even more with Handlebars

  script tags


  • Handlebars templates can be embedded in script tags.
  • You retrieve the HTML content from the script tag and pass it to the Handlebars compiler.
<script id="header" type="text/x-handlebars-template">
<div> Name: {{ headerTitle }} </div>
</script>
______________________________________________
 Boosting the client-side even more with Handlebars

  Context


  • Contains the data to be displayed on the page.
  • Passed as an object to the Handlebars function.
var theData = {
customers: [
{ firstName: ”John”, lastName: ”Doe”, age: 20 }, { { firstName: ”Chuck”, lastName: ”Norris”, age: 25 }
] };
<script id="header" type="text/x-handlebars-template">
{{#each customers}} <li> {{ firstName }} {{ lastName }} </li>
{{/each}} </script>
______________________________________________
 Boosting the client-side even more with Handlebars

  the handlebars compile function


  • Finally, in order to use our Handlebars template, we need to:
  1. Compile it with Handlebars compile function.
    It generates a JS function representing that template.
  2. Invoke that compiled function with our data.
 
 var theTemplate = Handlebars.compile(templateScript);
var html = theTemplate(theData); $(document.body).append(html);
______________________________________________
 Boosting the client-side even more with Handlebars

A Non-Handlebars vs A Handlebars project

  HTML File
    
<html>
    <head>
    <script type="text/javascript" src="jquery-1.9.1.min.js">
    </script>
    </head>
    <body>
    The List of Shoes:
    <ul class="shoesNav"></ul>
    </body>
    </html>
    ______________________________________________
     Boosting the client-side even more with Handlebars

    A Non-Handlebars project

    JS File
      $(function() { 
      var shoesData = [ { name: "Nike", price: 199.00 },
      { name: "Loafers", price: 59.00 },
      { name: "Wing Tip", price: 259.00 } ];
      function updateAllShoes(shoes) {
      var theHTMLListOfShoes = "";
      shoesData.forEach(function(eachShoe) {
      theHTMLListOfShoes += '<li class="shoes">' +
      '<a href="/' + eachShoe.name.toLowerCase() + '">' + eachShoe.name + ' -- Price: ' + eachShoe.price +
      '</a></li>';
      });
      return theHTMLListOfShoes;
      }
      $(".shoesNav").append(updateAllShoes(shoesData));
      });
      ______________________________________________
       Boosting the client-side even more with Handlebars

      A Handlebars project

        $(function() {
        var shoesData = [ { name: "Nike", price: 199.00 },
        { name: "Loafers", price: 59.00 },
        { name: "Wing Tip", price: 259.00 } ];
        var theTemplateScript = $("#shoe-template").html(); var theTemplate = Handlebars.compile(theTemplateScript);
        $(".shoesNav").append(theTemplate(shoesData));
        });
        <script id="shoe-template" type="x-handlebars-template">    
        {{#each this}}
        <li class="shoes">
        <a href="/{{name}}">{{name}} -- Price: {{price}} </a>
        </li>
        {{/each}}
        </script>

        ______________________________________________
         Boosting the client-side even more with Handlebars

        syntax


        • Expressions
        • Blocks
        • Paths
        • Parent Paths
        • Partials (sub-templates)
        • Helpers
          • Built-in Helpers
          • Custom Helpers
        ______________________________________________
          Boosting the client-side even more with Handlebars

          Blocks


        • Blocks in Handlebars are expressions within an opening {{# }} followed by a closing {{/ }}.
        {{#each}}
        
Content goes here.
        
{{/each}}
        • Here is an if block:
        {{#if someValueIsTrue}}
        
Content goes here
        
{{/if}} 
        ______________________________________________
          Boosting the client-side even more with Handlebars

          Paths


        • A path in Handlebars is a property lookup.
          var objData = {
          name: { firstName: "Michael", lastName:"Jackson" }
          }
        • We can use nested paths to lookup the property you want, like this:
            {{name.firstName}}    
          
        • ______________________________________________
            Boosting the client-side even more with Handlebars

          Partials (Sub-templates)



        • Sometimes you want to reuse a template inside a section of another. On this case you just need to invoke the partial expression:

          {{> partialName}}        

        ______________________________________________
          Boosting the client-side even more with Handlebars

          Helpers


        • Expressions that provide the necessary logic expressiveness on Handlebars Templates.

        • Built-In helpers: provides conditional and loop logic.
          • Each
          • If
          • Else
          • Unless

        ______________________________________________
          Boosting the client-side even more with Handlebars

          helpers - each


        • Used to iterate over an array or object.
        var data = {
        people: [
        "Chuck Norris",
        "Bruce Lee",
        "Jackie Chan"
        ] };
        <script id="peopleTemplate" type="text/x-handlebars-template">
        <ul class="people_list"> {{#each people}}
        <li>{{this}}</li> {{/each}}
        </ul>
        </script>
        __________________________________________
          Boosting the client-side even more with Handlebars

          helpers - EACH


        • If the data object passed to the each helper is not an array, the entire object is the current context and we use the this keyword.
        var data = {
        firstName: "Chuck",
        lastName: "Norris"
        };
        <script id="peopleTemplate" type="text/x-handlebars-template">
        <ul class="people_list">
        {{#each this}}
        <li>{{firstName}} {{lastName}}</li>
        {{/each}}
        </ul>
        </script>
        __________________________________________
          Boosting the client-side even more with Handlebars

          helpers - IF


        • Works like a regular IF conditional statement, except that it only accepts boolean values.
        • The block inside an IF Helper will only be rendered on the case the boolean is true.
        var data = {
        user: [ "Bond" ]
        };
        <script id="peopleTemplate" type="text/x-handlebars-template">
        <ul class="people_list"> {{#if user.length}} <li>{{user}}</li>
        {{/if}} </ul>
        </script>
        __________________________________________
          Boosting the client-side even more with Handlebars

          Custom helpers

        • Introduce flexibility on Handlebars.
        • They are created in JS code, not inside the templates.
        • Custom helpers allow creating any kind of JS logic.
          var data = {
          firstName: "Chuck",
          lastName: "Norris"
          };
          <script id="peoleTemplate" type="text/x-handlebars-template">
          <ul class="people_list"> {{#fullName this}}
          </ul>
          </script>
        • Output:
             <div> Chuck Norris </div>  
          
        __________________________________________
          Boosting the client-side even more with Handlebars

          Custom helpers


        • To be used, they need to be registered before all the rest of the Handlebars JS code.
        Handlebars.registerHelper('fullName', function(person) {   
        return person.first + ' ' + person.last;
        });
        __________________________________________
          Boosting the client-side even more with Handlebars

        Conclusion


        • Thick Clients is not a web trend to be ignored.

        • Client-side Templating is a great web solution and worth to give it a try.

        • Handlebars is a powerful & great tool for this endeavor.


          ______________________________________________
           Boosting the client-side even more with Handlebars

          Learn more


          ______________________________________________
           Boosting the client-side even more with Handlebars

          Assignment

          Refactor the multiple-choice quiz code given on the last talks using Handlebars. Keep in mind the following:

          1. Use and abuse of Handlebars blocks of expressions.
          2. Make sure you use the following:
            • Handlebars Path (property lookup) - 2x
            • A sub-template.
            • Each of these built-in Helpers: Each, If, Else, Unless
            • A custom helper.
          3. Extra:
            • Pre-compile your Handlebars template.
            • Make use of one Handlebars Parent Path lookup.
          4. Send me the solution in a GitHub repo. 





          extra

            Parent Path

          Parent path ../ allows to lookup properties on parents of the current context.
          var shoesData = { 
          groupName: "Celebrities",
          users: [ { name: { first : "John", last: "Doe" } },
          { name: { first : "John", last: "Waters" } } ] };
          <script id="shoe-template" type="x-handlebars-template">
          {{#users}}
          <li>
          {{name.first}} {{name.last}} is in the {{../groupName}} group
          </li>
          {{/users}}
          </script>
          Mike Alexander is in the Celebrities group.
          John Waters is in the Celebrities group.  
          
          ______________________________________________
           Boosting the client-side even more with Handlebars
          Made with Slides.com