Using Templates to Achieve Awesomer Architecture
Upcoming SlideShare
Loading in...5
×
 

Using Templates to Achieve Awesomer Architecture

on

  • 26,579 views

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, ...

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.

Statistics

Views

Total Views
26,579
Views on SlideShare
25,661
Embed Views
918

Actions

Likes
57
Downloads
414
Comments
6

22 Embeds 918

http://www.garann.com 675
http://treehouseagency.com 44
http://speakerrate.com 31
http://beecommunity.beetroid.com 29
http://paper.li 28
https://si0.twimg.com 26
http://www.linkedin.com 24
http://localhost 24
https://twimg0-a.akamaihd.net 8
https://www.linkedin.com 6
http://us-w1.rockmelt.com 5
http://www.phase2technology.com 5
http://a0.twimg.com 3
http://my-videoss.blogspot.com 2
https://twitter.com 1
http://my-videoss.blogspot.ca 1
http://p2web.p2devcloud.fayze2.com 1
http://tweetedtimes.com 1
http://my-videoss.blogspot.de 1
http://alpha.beetroid.com 1
http://translate.googleusercontent.com 1
http://zootool.com 1
More...

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

Using Templates to Achieve Awesomer Architecture Using Templates to Achieve Awesomer Architecture Presentation Transcript

  • using templates to achieve AWESOMER architecture Sunday, October 17, 2010
  • 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
  • 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”); 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
  • 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
  • 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
  • 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
  • that’s not an architecture #thatsaproblem Sunday, October 17, 2010
  • 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
  • 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”> <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
  • 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
  • exciting syntax! Sunday, October 17, 2010
  • properties ${bandName} is the world’s greatest band. Everyone loves {{= bandName}}. Sunday, October 17, 2010
  • 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
  • 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
  • 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
  • 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
  • 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
  • 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
  • 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
  • how do they work? Sunday, October 17, 2010
  • rendering $.tmpl(“comments”,data.comments).appendTo (“#container”); $(“#comment-tmpl”).tmpl (data.comments).appendTo(“#container”); $(document).html($(“#justsayin”).tmpl(data)); Sunday, October 17, 2010
  • $.tmpl String immediately parsed and evaluated Tags translated to expressions Return a jQuery object Sunday, October 17, 2010
  • compiling $.template(“veryShortTmpl”,”<b>${name}</b>”); $(“#stuff-tmpl”).template(“wickedCoolTmpl”); Sunday, October 17, 2010
  • $.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
  • 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
  • $.tmplItem tmplItem has additional functions and properties nodes, parent, html, nest, wrap Functions remain available to object in DOM Sunday, October 17, 2010
  • event handling Sunday, October 17, 2010
  • weak $(“#some-tmpl”).tmpl(data).appendTo(“#thing”); $(“a.childOfThing”).click(function(e) { e.preventDefault(); doMoreStuff(); }); Sunday, October 17, 2010
  • 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
  • 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
  • when the only tool you have is a hammer.. oh wait you have CSS Sunday, October 17, 2010
  • awesome $(“#some-tmpl”).tmpl(data).appendTo(“#thing”); $(“#childOfThing”).tmplItem().tmpl = $(“#state-two-tmpl”).template(); Sunday, October 17, 2010
  • AWESOMER! use CSS where possible - it’s faster! $(“#some-tmpl”).tmpl(data).appendTo(“#thing”); $(“#childOfThing”) .removeClass(“stateOne”) .addClass(“stateTwo”); Sunday, October 17, 2010
  • 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
  • fast, good, cheap: pick two and a half Sunday, October 17, 2010
  • faster-ish templates break up the family separate pattern templates from interface templates Always Be Compiling templates = functions Sunday, October 17, 2010
  • stop sending html Sunday, October 17, 2010
  • pagination myApp.container = $(“#stuffContainer”); $(“a.showMore”).click(function() { $.get(“/moreStuff”,function(items) { $(“#item-tmpl”) .tmpl(items) .appendTo(myApp.container); }); }); Sunday, October 17, 2010
  • 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
  • inline edit $(“#anEditButton”).live(“click”,function() { $(“#thisGuysParent”) .tmplItem() .tmpl = $(“#edit-mode-tmpl”).template(); }); Sunday, October 17, 2010
  • yo dawg we heard you like plugins Sunday, October 17, 2010
  • 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
  • AWESOMER! $.fn.myPlugin = function(options) { this.html($.tmpl(“myTemplate”,options)); ... return this; } Sunday, October 17, 2010
  • weak $.fn.myPlugin.update = function(newOpts) { this.html(‘<div class=”’ + newOpts.class + ’”>’ + newOpts.content + ‘<a href=”#”>’ + newOpts.buttonLabel + ‘</a></div>’); ... } Sunday, October 17, 2010
  • AWESOMER! $.fn.myPlugin.update = function(newOpts) { this.tmplItem().data = newOpts; ... } Sunday, October 17, 2010
  • AWESOMER plugins No more DOM manipulation Don’t have to require a template engine * Sexy updates and redraws Sunday, October 17, 2010
  • where do templates come from? Sunday, October 17, 2010
  • 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
  • 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
  • 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
  • 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
  • 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
  • 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 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
  • 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.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
  • i appreciate ya! keep in touch: @garannm / garann@gmail.com demo code: github.com/garann/templates-example Sunday, October 17, 2010