Your SlideShare is downloading. ×
0
using templates to achieve

                           AWESOMER
                           architecture


Sunday, October ...
hi!
                   Garann “it’s like Karen with a G” Means

                   HTML, CSS, JS at Gerson Lehrman Group

...
ask me how i reduced 12k
                      lines of js to 4k



Sunday, October 17, 2010
get that now
                   http://github.com/jquery/jquery-tmpl




Sunday, October 17, 2010
alternatives?




Sunday, October 17, 2010
dom manipulation
              var container = $(“div.band-info”);
              container.append(“h2”);
              con...
hidden element “templates”
              var container = $(“div.band-info”);
              container.find(“h2”).html(band....
concatenation
              var html = new Array();
              html.push(‘<div class=”band-info”><h2>’);
              ...
what about just returning
                     html from an xhr?
                   send the same data over and over

    ...
that’s not an architecture
                           #thatsaproblem




Sunday, October 17, 2010
an AWESOMER architecture:
                   separates the presentation from the data

                   abstracts views ...
pros and cons




                     no templates         templates
Sunday, October 17, 2010
performance
Sunday, October 17, 2010
DRY
Sunday, October 17, 2010
minimize dom manipulation
Sunday, October 17, 2010
maintainability
Sunday, October 17, 2010
lazy loading
Sunday, October 17, 2010
what a template looks like
              <script type=”text/html”>
               <div class=”band-info”>
                ...
what a template looks like
              <script type=”text/html”>
               <div class=”band-info”>
                ...
exciting syntax!




Sunday, October 17, 2010
properties
              ${bandName} is the world’s greatest band.

              Everyone loves {{= bandName}}.




Sunda...
expressions
              ${bandName} has ${fans.length} fans

              ${bandName} has ${fans.length}
              ...
if / else
              {{if fans.length}}

                  ${bandName} has ${fans.length}
                   ${myApp.pl...
each
              {{each members}}

                  ${$value.name} plays the ${$value.instrument}
                  lik...
nested template
              <script type=”text/html” id=”footer-tmpl”>
               Comments:
               {{tmpl(co...
compiled template
              <script type=”text/html” id=”footer-tmpl”>
               Comments:
               {{tmpl(...
other tags
                   {{! this is a comment}}

                   {{html thingThatShouldntBeEscaped}}

           ...
this
                   main template: refer to properties directly

                   $item, $item.data, $data

        ...
how do they work?




Sunday, October 17, 2010
rendering
              $.tmpl(“comments”,data.comments).appendTo
              (“#container”);

              $(“#comment...
$.tmpl
                   String immediately parsed and evaluated

                   Tags translated to expressions

    ...
compiling
              $.template(“veryShortTmpl”,”<b>${name}</b>”);

              $(“#stuff-tmpl”).template(“wickedCool...
$.template
                   Parse the template but don’t populate

                   Template engine saves in a big ol’...
get and set
              var t = $(“div.comment:last”).tmplItem();

              var lastId = t.data.id;

              ...
$.tmplItem
                   tmplItem has additional functions and properties

                           nodes, parent, ...
event handling




Sunday, October 17, 2010
weak
              $(“#some-tmpl”).tmpl(data).appendTo(“#thing”);

              $(“a.childOfThing”).click(function(e) {
 ...
awesome
                   use live() for events on multiple pages

                   or for things that change container...
AWESOMER!
                   use delegate() for events on one page

                   or always in the same container

  ...
when the only tool you
                            have is a hammer..
                                oh wait you have CSS...
awesome
              $(“#some-tmpl”).tmpl(data).appendTo(“#thing”);

              $(“#childOfThing”).tmplItem().tmpl =
 ...
AWESOMER!
                   use CSS where possible - it’s faster!




              $(“#some-tmpl”).tmpl(data).appendTo(“...
css is better for..
                   errors

                   small number of elements being shown/hidden

           ...
fast, good, cheap:
                           pick two and a half



Sunday, October 17, 2010
faster-ish templates
                   break up the family

                   separate pattern templates from interface ...
stop sending html




Sunday, October 17, 2010
pagination
              myApp.container = $(“#stuffContainer”);

              $(“a.showMore”).click(function() {

      ...
polling for new data
              window.setTimeout(checkForStuff, 30000);

              function checkForStuff() {
    ...
inline edit
              $(“#anEditButton”).live(“click”,function() {
               $(“#thisGuysParent”)
               ...
yo dawg we heard you like
                       plugins



Sunday, October 17, 2010
weak
              $.fn.myPlugin = function(options) {
                this.html(‘<div class=”’ + options.class +
        ...
AWESOMER!
              $.fn.myPlugin = function(options) {
                this.html($.tmpl(“myTemplate”,options));
     ...
weak
              $.fn.myPlugin.update = function(newOpts) {
                this.html(‘<div class=”’ + newOpts.class +
 ...
AWESOMER!
              $.fn.myPlugin.update = function(newOpts) {
                this.tmplItem().data = newOpts;
       ...
AWESOMER plugins
                   No more DOM manipulation

                   Don’t have to require a template engine *...
where do templates come
                          from?



Sunday, October 17, 2010
in your javascript
              var myTemplate = ‘<div class="band-info"><img
              src="/images/${photo}" alt="$...
in your html
              <script type=”text/html” id=”my-tmpl”>
               <div class="band-info">
                 ...
external files
              if ($.template("commentTmpl").length) {
                updateComment(comment);
             ...
use external files if you enjoy:
                   Having your templates cached

                   Only loading code onc...
little external templates
                   put lots of little strings in one file

                   like a constants f...
what about clients without
                          js?



Sunday, October 17, 2010
noscripts
                   srsly?

                   clientside templates on the serverside




Sunday, October 17, 2010
two-fer-one




Sunday, October 17, 2010
#newtwitter’s doing it
Sunday, October 17, 2010
node.js is doing it
Sunday, October 17, 2010
takes a little doing
                   have to write a backend parser

                   may limit native functions like...
does this template engine
                      come in green?



Sunday, October 17, 2010
micro-templates
Sunday, October 17, 2010
mustache
Sunday, October 17, 2010
jTemplates
Sunday, October 17, 2010
pure
Sunday, October 17, 2010
check out:
              jQuery templates: github.com/jquery/jquery-tmpl/

              documentation: http://api.jquery....
i appreciate ya!


            keep in touch: @garannm / garann@gmail.com
          demo code: github.com/garann/templates...
Upcoming SlideShare
Loading in...5
×

Using Templates to Achieve Awesomer Architecture

29,855

Published on

Templates are the best kind of tool: simple to write and implement, but powerful enough to make your architecture slicker and your code leaner. Getting markup out of your Javascript is a huge deal, but templates can help with more than that. They can manage repeated code snippets, allow you to deftly switch states in single page applications, and help keep your code DRY when supporting users with and without Javascript enabled. Using and extending them creatively can make any architecture a little awesomer.

Published in: Technology
6 Comments
61 Likes
Statistics
Notes
No Downloads
Views
Total Views
29,855
On Slideshare
0
From Embeds
0
Number of Embeds
8
Actions
Shares
0
Downloads
426
Comments
6
Likes
61
Embeds 0
No embeds

No notes for slide

Transcript of "Using Templates to Achieve Awesomer Architecture"

  1. 1. using templates to achieve AWESOMER architecture Sunday, October 17, 2010
  2. 2. hi! Garann “it’s like Karen with a G” Means HTML, CSS, JS at Gerson Lehrman Group Austin, TX garann.com / garann@gmail.com / @garannm Sunday, October 17, 2010
  3. 3. ask me how i reduced 12k lines of js to 4k Sunday, October 17, 2010
  4. 4. get that now http://github.com/jquery/jquery-tmpl Sunday, October 17, 2010
  5. 5. alternatives? Sunday, October 17, 2010
  6. 6. dom manipulation var container = $(“div.band-info”); container.append(“h2”); container.find(“h2”).html(band.bandName); $.each(band.members,function() { var span = container.append(“span”) .addClass(“band-member”); span.html(this.name+“ - “+this.instrument); }); if (band.single) { var link = container.append(“a”) .attr(“href”,band.single.url); link .text(‘Download “‘+band.single.title+‘“‘); } Sunday, October 17, 2010
  7. 7. hidden element “templates” var container = $(“div.band-info”); container.find(“h2”).html(band.bandName); var link = container.find(“a”); $.each(band.members,function() { link.before(‘<span class=”band-member”>’ + this.name + ‘ - ‘ + this.instrument + ‘</ span>’); }); if (band.single) { link.attr(“href”,band.single.url); link.text(band.single.title); } else { link.hide(); } ps: still dom manipulation Sunday, October 17, 2010
  8. 8. concatenation var html = new Array(); html.push(‘<div class=”band-info”><h2>’); html.push(band.bandName + ‘</h2>’); $.each(band.members,function() { html.push(‘<span class=”band-member”>’); html.push(this.name + ‘ - ‘); html.push(this.instrument + ‘</span>’); }); if (band.single) { html.push(‘<a href=”’ + band.single.url); html.push(‘”>Download “‘); html.push(band.single.title + ‘”</a>’); } html.push(‘</div>’); document.append(html.join(“”)); Sunday, October 17, 2010
  9. 9. what about just returning html from an xhr? send the same data over and over have to dig properties out of DOM building HTML server-side is annoying Sunday, October 17, 2010
  10. 10. that’s not an architecture #thatsaproblem Sunday, October 17, 2010
  11. 11. an AWESOMER architecture: separates the presentation from the data abstracts views into reusable components markup changes in one place flexibility to treat big and small views differently where you need it when you need it Sunday, October 17, 2010
  12. 12. pros and cons no templates templates Sunday, October 17, 2010
  13. 13. performance Sunday, October 17, 2010
  14. 14. DRY Sunday, October 17, 2010
  15. 15. minimize dom manipulation Sunday, October 17, 2010
  16. 16. maintainability Sunday, October 17, 2010
  17. 17. lazy loading Sunday, October 17, 2010
  18. 18. what a template looks like <script type=”text/html”> <div class=”band-info”> <h2>${bandName}</h2> {{each members}} <span class=”band-member”> ${$value.name} - ${$value.instrument} </span> {{/each}} {{if single}} <a href=”${single.url}”> Download “${single.title}”</a> {{/if}} </div> </script> Sunday, October 17, 2010
  19. 19. what a template looks like <script type=”text/html”> <div class=”band-info”> <h2>${bandName}</h2> {{each members}} <span class=”band-member”> ${$value.name} - ${$value.instrument} </span> {{/each}} {{if single}} <a href=”${single.url}”> Download “${single.title}”</a> {{/if}} </div> </script> Sunday, October 17, 2010
  20. 20. exciting syntax! Sunday, October 17, 2010
  21. 21. properties ${bandName} is the world’s greatest band. Everyone loves {{= bandName}}. Sunday, October 17, 2010
  22. 22. expressions ${bandName} has ${fans.length} fans ${bandName} has ${fans.length} fan${fans.length == 1 ? ‘’ : ‘s’} ${bandName} has ${fans.length} ${myApp.pluralize(‘fan’)} Sunday, October 17, 2010
  23. 23. if / else {{if fans.length}} ${bandName} has ${fans.length} ${myApp.pluralize(‘fan’)} {{else}} You’ve probably never heard of ${bandName}. They’re really obscure. {{/if}} Sunday, October 17, 2010
  24. 24. each {{each members}} ${$value.name} plays the ${$value.instrument} like a GOD. You heard me. ${this.name} practically invented the ${this.instrument}. {{/each}} Sunday, October 17, 2010
  25. 25. nested template <script type=”text/html” id=”footer-tmpl”> Comments: {{tmpl(comments) “#comment-tmpl”}} </script> <script type=”text/html” id=”comment-tmpl”> <div class="comment"> <span class="commentor"> ${commentor} said:</span> <p>${text}</p> <span class="timestamp">on ${timestamp.toLocaleDateString()}</span> </div> </script> Sunday, October 17, 2010
  26. 26. compiled template <script type=”text/html” id=”footer-tmpl”> Comments: {{tmpl(comments) “commentTempl”}} </script> <script type=”text/html” id=”comment-tmpl”> <div class=”comment”> <span>${commentor} said:</span> <p>${text}</p> <span>on ${timestamp.toDateString()}</span> </div> </script> <script type=”text/javascript”> $(“#comment-tmpl”).template(“commentTempl”); </script> Sunday, October 17, 2010
  27. 27. other tags {{! this is a comment}} {{html thingThatShouldntBeEscaped}} {{wrap "#otherTmpl”}} <div class=”thing”>One</div> <div class=”otherThing”>Two</div> {{/wrap}} Sunday, October 17, 2010
  28. 28. this main template: refer to properties directly $item, $item.data, $data {{each}}: $value nested template: parent’s data or whatever you passed in Sunday, October 17, 2010
  29. 29. how do they work? Sunday, October 17, 2010
  30. 30. rendering $.tmpl(“comments”,data.comments).appendTo (“#container”); $(“#comment-tmpl”).tmpl (data.comments).appendTo(“#container”); $(document).html($(“#justsayin”).tmpl(data)); Sunday, October 17, 2010
  31. 31. $.tmpl String immediately parsed and evaluated Tags translated to expressions Return a jQuery object Sunday, October 17, 2010
  32. 32. compiling $.template(“veryShortTmpl”,”<b>${name}</b>”); $(“#stuff-tmpl”).template(“wickedCoolTmpl”); Sunday, October 17, 2010
  33. 33. $.template Parse the template but don’t populate Template engine saves in a big ol’ list Rendering with data like calling a function Sunday, October 17, 2010
  34. 34. get and set var t = $(“div.comment:last”).tmplItem(); var lastId = t.data.id; t.tmpl = $.template(“new-tmpl”); t.update(); Sunday, October 17, 2010
  35. 35. $.tmplItem tmplItem has additional functions and properties nodes, parent, html, nest, wrap Functions remain available to object in DOM Sunday, October 17, 2010
  36. 36. event handling Sunday, October 17, 2010
  37. 37. weak $(“#some-tmpl”).tmpl(data).appendTo(“#thing”); $(“a.childOfThing”).click(function(e) { e.preventDefault(); doMoreStuff(); }); Sunday, October 17, 2010
  38. 38. awesome use live() for events on multiple pages or for things that change containers // in some function $(“#some-tmpl”).tmpl(data).appendTo(“#thing”); // wherever $(“a.childOfThing”).live(“click”,function(e) { e.preventDefault(); doMoreStuff(); }); Sunday, October 17, 2010
  39. 39. AWESOMER! use delegate() for events on one page or always in the same container // in some function $(“#some-tmpl”).tmpl(data).appendTo(“#thing”); // wherever $(“#thing”).delegate( “a.childOfThing”,“click”,function(e) { e.preventDefault(); doMoreStuff(); }); Sunday, October 17, 2010
  40. 40. when the only tool you have is a hammer.. oh wait you have CSS Sunday, October 17, 2010
  41. 41. awesome $(“#some-tmpl”).tmpl(data).appendTo(“#thing”); $(“#childOfThing”).tmplItem().tmpl = $(“#state-two-tmpl”).template(); Sunday, October 17, 2010
  42. 42. AWESOMER! use CSS where possible - it’s faster! $(“#some-tmpl”).tmpl(data).appendTo(“#thing”); $(“#childOfThing”) .removeClass(“stateOne”) .addClass(“stateTwo”); Sunday, October 17, 2010
  43. 43. css is better for.. errors small number of elements being shown/hidden elements with plugins attached input areas that may have unsubmitted user data Sunday, October 17, 2010
  44. 44. fast, good, cheap: pick two and a half Sunday, October 17, 2010
  45. 45. faster-ish templates break up the family separate pattern templates from interface templates Always Be Compiling templates = functions Sunday, October 17, 2010
  46. 46. stop sending html Sunday, October 17, 2010
  47. 47. pagination myApp.container = $(“#stuffContainer”); $(“a.showMore”).click(function() { $.get(“/moreStuff”,function(items) { $(“#item-tmpl”) .tmpl(items) .appendTo(myApp.container); }); }); Sunday, October 17, 2010
  48. 48. polling for new data window.setTimeout(checkForStuff, 30000); function checkForStuff() { $.get(“/moreStuff”,function(items) { if (items.length) { var d = {l: items.length, d: items }; $(“#load-new-btn-tmpl”).tmpl(d) .prependTo(myApp.container); } window.setTimeout(checkForStuff, 30000); }); } $(“#loadNewBtn”).live(“click”,function(e) { $(this).tmplItem().tmpl = $.template(“new-tmpl”); }); Sunday, October 17, 2010
  49. 49. inline edit $(“#anEditButton”).live(“click”,function() { $(“#thisGuysParent”) .tmplItem() .tmpl = $(“#edit-mode-tmpl”).template(); }); Sunday, October 17, 2010
  50. 50. yo dawg we heard you like plugins Sunday, October 17, 2010
  51. 51. weak $.fn.myPlugin = function(options) { this.html(‘<div class=”’ + options.class + ’”>’ + options.content + ‘<a href=”#”>’ + options.buttonLabel + ‘</a></div>’); ... return this; } Sunday, October 17, 2010
  52. 52. AWESOMER! $.fn.myPlugin = function(options) { this.html($.tmpl(“myTemplate”,options)); ... return this; } Sunday, October 17, 2010
  53. 53. weak $.fn.myPlugin.update = function(newOpts) { this.html(‘<div class=”’ + newOpts.class + ’”>’ + newOpts.content + ‘<a href=”#”>’ + newOpts.buttonLabel + ‘</a></div>’); ... } Sunday, October 17, 2010
  54. 54. AWESOMER! $.fn.myPlugin.update = function(newOpts) { this.tmplItem().data = newOpts; ... } Sunday, October 17, 2010
  55. 55. AWESOMER plugins No more DOM manipulation Don’t have to require a template engine * Sexy updates and redraws Sunday, October 17, 2010
  56. 56. where do templates come from? Sunday, October 17, 2010
  57. 57. in your javascript var myTemplate = ‘<div class="band-info"><img src="/images/${photo}" alt="${bandName}" / ><h2>${bandName}</h2>{{each members}} ! ! ! ! <span class="band-member"> ! ! ! ! ! ${this.name} - ${this.instrument} ! ! ! ! </span> ! ! ! {{/each}}</div>’; $.tmpl(myTemplate,data).appendTo(container); eeeeek. Sunday, October 17, 2010
  58. 58. in your html <script type=”text/html” id=”my-tmpl”> <div class="band-info"> <img src="/images/${photo}" alt="${bandName}" /> <h2>${bandName}</h2> {{each members}} ! ! ! ! <span class="band-member"> ! ! ! ! ! ${this.name} - ${this.instrument} ! ! ! ! </span> ! ! ! {{/each}} </div> </script> $(“#my-tmpl”).tmpl(data).appendTo(container); Sunday, October 17, 2010
  59. 59. external files if ($.template("commentTmpl").length) { updateComment(comment); } else { $.get("comment-tmpl.js", function(response) { $.template("commentTmpl",response); updateComment(comment); }); } function updateComment(comment) { // rendering happens here } hint: ftw Sunday, October 17, 2010
  60. 60. use external files if you enjoy: Having your templates cached Only loading code once it’s needed Better code organization Using your client-side templates for server-side rendering Sunday, October 17, 2010
  61. 61. little external templates put lots of little strings in one file like a constants file e.g. internationalization small patterns available everywhere Sunday, October 17, 2010
  62. 62. what about clients without js? Sunday, October 17, 2010
  63. 63. noscripts srsly? clientside templates on the serverside Sunday, October 17, 2010
  64. 64. two-fer-one Sunday, October 17, 2010
  65. 65. #newtwitter’s doing it Sunday, October 17, 2010
  66. 66. node.js is doing it Sunday, October 17, 2010
  67. 67. takes a little doing have to write a backend parser may limit native functions like length() unless your backend is JS custom functions pretty much out unless your backend is JS even truthy and falsey may be a problem DEMO NAO PLZ now you’re just showing off. Sunday, October 17, 2010
  68. 68. does this template engine come in green? Sunday, October 17, 2010
  69. 69. micro-templates Sunday, October 17, 2010
  70. 70. mustache Sunday, October 17, 2010
  71. 71. jTemplates Sunday, October 17, 2010
  72. 72. pure Sunday, October 17, 2010
  73. 73. check out: jQuery templates: github.com/jquery/jquery-tmpl/ documentation: http://api.jquery.com/ (scroll to the very bottom) jQuery templates for node.js: github.com/kof/node-jqtpl jQuery templates for .NET: github.com/awhatley/jquery-tmpl.net photo credit: http://www.flickr.com/photos/ennuiislife/ Sunday, October 17, 2010
  74. 74. i appreciate ya! keep in touch: @garannm / garann@gmail.com demo code: github.com/garann/templates-example Sunday, October 17, 2010
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×