Using Templates to Achieve Awesomer Architecture

74
using templates to achieve AWESOMER architecture Sunday, October 17, 2010

description

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.

Transcript of Using Templates to Achieve Awesomer Architecture

Page 1: Using Templates to Achieve Awesomer Architecture

using templates to achieve

AWESOMER architecture

Sunday, October 17, 2010

Page 2: Using Templates to Achieve Awesomer Architecture

hi!Garann “it’s like Karen with a G” Means

HTML, CSS, JS at Gerson Lehrman Group

Austin, TX

garann.com / [email protected] / @garannm

Sunday, October 17, 2010

Page 3: Using Templates to Achieve Awesomer Architecture

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

Sunday, October 17, 2010

Page 4: Using Templates to Achieve Awesomer Architecture

get that nowhttp://github.com/jquery/jquery-tmpl

Sunday, October 17, 2010

Page 5: Using Templates to Achieve Awesomer Architecture

alternatives?

Sunday, October 17, 2010

Page 6: Using Templates to Achieve Awesomer Architecture

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+‘“‘);

}

dom manipulation

Sunday, October 17, 2010

Page 7: Using Templates to Achieve Awesomer Architecture

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();

}

hidden element “templates”

ps: still dom manipulationSunday, October 17, 2010

Page 8: Using Templates to Achieve Awesomer Architecture

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(“”));

concatenation

Sunday, October 17, 2010

Page 9: Using Templates to Achieve Awesomer Architecture

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

Page 10: Using Templates to Achieve Awesomer Architecture

that’s not an architecture#thatsaproblem

Sunday, October 17, 2010

Page 11: Using Templates to Achieve Awesomer Architecture

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

Page 12: Using Templates to Achieve Awesomer Architecture

pros and cons

no templates templatesSunday, October 17, 2010

Page 13: Using Templates to Achieve Awesomer Architecture

performanceSunday, October 17, 2010

Page 14: Using Templates to Achieve Awesomer Architecture

DRYSunday, October 17, 2010

Page 15: Using Templates to Achieve Awesomer Architecture

minimize dom manipulationSunday, October 17, 2010

Page 16: Using Templates to Achieve Awesomer Architecture

maintainabilitySunday, October 17, 2010

Page 17: Using Templates to Achieve Awesomer Architecture

lazy loadingSunday, October 17, 2010

Page 18: Using Templates to Achieve Awesomer Architecture

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

what a template looks like

Sunday, October 17, 2010

Page 19: Using Templates to Achieve Awesomer Architecture

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

what a template looks like

Sunday, October 17, 2010

Page 20: Using Templates to Achieve Awesomer Architecture

exciting syntax!

Sunday, October 17, 2010

Page 21: Using Templates to Achieve Awesomer Architecture

${bandName} is the world’s greatest band.

Everyone loves {{= bandName}}.

properties

Sunday, October 17, 2010

Page 22: Using Templates to Achieve Awesomer Architecture

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

${bandName} has ${fans.length} fan${fans.length == 1 ? ‘’ : ‘s’}

${bandName} has ${fans.length} ${myApp.pluralize(‘fan’)}

expressions

Sunday, October 17, 2010

Page 23: Using Templates to Achieve Awesomer Architecture

{{if fans.length}}

${bandName} has ${fans.length}${myApp.pluralize(‘fan’)}

{{else}}

You’ve probably never heard of ${bandName}. They’re really obscure.

{{/if}}

if / else

Sunday, October 17, 2010

Page 24: Using Templates to Achieve Awesomer Architecture

{{each members}}

${$value.name} plays the ${$value.instrument} like a GOD.

You heard me. ${this.name} practically invented the ${this.instrument}.

{{/each}}

each

Sunday, October 17, 2010

Page 25: Using Templates to Achieve Awesomer Architecture

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

nested template

Sunday, October 17, 2010

Page 26: Using Templates to Achieve Awesomer Architecture

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

compiled template

Sunday, October 17, 2010

Page 27: Using Templates to Achieve Awesomer Architecture

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

Page 28: Using Templates to Achieve Awesomer Architecture

thismain 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

Page 29: Using Templates to Achieve Awesomer Architecture

how do they work?

Sunday, October 17, 2010

Page 30: Using Templates to Achieve Awesomer Architecture

$.tmpl(“comments”,data.comments).appendTo(“#container”);

$(“#comment-tmpl”).tmpl(data.comments).appendTo(“#container”);

$(document).html($(“#justsayin”).tmpl(data));

rendering

Sunday, October 17, 2010

Page 31: Using Templates to Achieve Awesomer Architecture

$.tmplString immediately parsed and evaluated

Tags translated to expressions

Return a jQuery object

Sunday, October 17, 2010

Page 32: Using Templates to Achieve Awesomer Architecture

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

$(“#stuff-tmpl”).template(“wickedCoolTmpl”);

compiling

Sunday, October 17, 2010

Page 33: Using Templates to Achieve Awesomer Architecture

$.templateParse 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

Page 34: Using Templates to Achieve Awesomer Architecture

var t = $(“div.comment:last”).tmplItem();

var lastId = t.data.id;

t.tmpl = $.template(“new-tmpl”);t.update();

get and set

Sunday, October 17, 2010

Page 35: Using Templates to Achieve Awesomer Architecture

$.tmplItemtmplItem has additional functions and properties

nodes, parent, html, nest, wrap

Functions remain available to object in DOM

Sunday, October 17, 2010

Page 36: Using Templates to Achieve Awesomer Architecture

event handling

Sunday, October 17, 2010

Page 37: Using Templates to Achieve Awesomer Architecture

$(“#some-tmpl”).tmpl(data).appendTo(“#thing”);

$(“a.childOfThing”).click(function(e) {e.preventDefault();doMoreStuff();

});

weak

Sunday, October 17, 2010

Page 38: Using Templates to Achieve Awesomer Architecture

// in some function$(“#some-tmpl”).tmpl(data).appendTo(“#thing”);

// wherever$(“a.childOfThing”).live(“click”,function(e) {e.preventDefault();doMoreStuff();

});

awesomeuse live() for events on multiple pages

or for things that change containers

Sunday, October 17, 2010

Page 39: Using Templates to Achieve Awesomer Architecture

// in some function$(“#some-tmpl”).tmpl(data).appendTo(“#thing”);

// wherever$(“#thing”).delegate(“a.childOfThing”,“click”,function(e) {e.preventDefault();doMoreStuff();

});

AWESOMER!use delegate() for events on one page

or always in the same container

Sunday, October 17, 2010

Page 40: Using Templates to Achieve Awesomer Architecture

when the only tool you have is a hammer..

oh wait you have CSS

Sunday, October 17, 2010

Page 41: Using Templates to Achieve Awesomer Architecture

$(“#some-tmpl”).tmpl(data).appendTo(“#thing”);

$(“#childOfThing”).tmplItem().tmpl =$(“#state-two-tmpl”).template();

awesome

Sunday, October 17, 2010

Page 42: Using Templates to Achieve Awesomer Architecture

$(“#some-tmpl”).tmpl(data).appendTo(“#thing”);

$(“#childOfThing”).removeClass(“stateOne”).addClass(“stateTwo”);

AWESOMER!use CSS where possible - it’s faster!

Sunday, October 17, 2010

Page 43: Using Templates to Achieve Awesomer Architecture

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

Page 44: Using Templates to Achieve Awesomer Architecture

fast, good, cheap:pick two and a half

Sunday, October 17, 2010

Page 45: Using Templates to Achieve Awesomer Architecture

faster-ish templatesbreak up the family

separate pattern templates from interface templates

Always Be Compiling

templates = functions

Sunday, October 17, 2010

Page 46: Using Templates to Achieve Awesomer Architecture

stop sending html

Sunday, October 17, 2010

Page 47: Using Templates to Achieve Awesomer Architecture

myApp.container = $(“#stuffContainer”);

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

$.get(“/moreStuff”,function(items) {

$(“#item-tmpl”).tmpl(items).appendTo(myApp.container);

});

});

pagination

Sunday, October 17, 2010

Page 48: Using Templates to Achieve Awesomer Architecture

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”);

});

polling for new data

Sunday, October 17, 2010

Page 49: Using Templates to Achieve Awesomer Architecture

$(“#anEditButton”).live(“click”,function() {$(“#thisGuysParent”).tmplItem().tmpl = $(“#edit-mode-tmpl”).template();

});

inline edit

Sunday, October 17, 2010

Page 50: Using Templates to Achieve Awesomer Architecture

yo dawg we heard you like plugins

Sunday, October 17, 2010

Page 51: Using Templates to Achieve Awesomer Architecture

$.fn.myPlugin = function(options) {this.html(‘<div class=”’ + options.class + ’”>’ + options.content + ‘<a href=”#”>’ +options.buttonLabel + ‘</a></div>’);

...return this;

}

weak

Sunday, October 17, 2010

Page 52: Using Templates to Achieve Awesomer Architecture

$.fn.myPlugin = function(options) {this.html($.tmpl(“myTemplate”,options));...return this;

}

AWESOMER!

Sunday, October 17, 2010

Page 53: Using Templates to Achieve Awesomer Architecture

$.fn.myPlugin.update = function(newOpts) {this.html(‘<div class=”’ + newOpts.class + ’”>’ + newOpts.content + ‘<a href=”#”>’ +newOpts.buttonLabel + ‘</a></div>’);...

}

weak

Sunday, October 17, 2010

Page 54: Using Templates to Achieve Awesomer Architecture

$.fn.myPlugin.update = function(newOpts) {this.tmplItem().data = newOpts;...

}

AWESOMER!

Sunday, October 17, 2010

Page 55: Using Templates to Achieve Awesomer Architecture

AWESOMER pluginsNo more DOM manipulation

Don’t have to require a template engine *

Sexy updates and redraws

Sunday, October 17, 2010

Page 56: Using Templates to Achieve Awesomer Architecture

where do templates come from?

Sunday, October 17, 2010

Page 57: Using Templates to Achieve Awesomer Architecture

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);

in your javascript

eeeeek.Sunday, October 17, 2010

Page 58: Using Templates to Achieve Awesomer Architecture

<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);

in your html

Sunday, October 17, 2010

Page 59: Using Templates to Achieve Awesomer Architecture

if ($.template("commentTmpl").length) {updateComment(comment);

} else {$.get("comment-tmpl.js", function(response) {

$.template("commentTmpl",response);updateComment(comment);

});}

function updateComment(comment) {// rendering happens here

}

external files

hint: ftwSunday, October 17, 2010

Page 60: Using Templates to Achieve Awesomer Architecture

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

Page 61: Using Templates to Achieve Awesomer Architecture

little external templatesput lots of little strings in one file

like a constants file

e.g. internationalization

small patterns available everywhere

Sunday, October 17, 2010

Page 62: Using Templates to Achieve Awesomer Architecture

what about clients without js?

Sunday, October 17, 2010

Page 63: Using Templates to Achieve Awesomer Architecture

noscriptssrsly?

clientside templates on the serverside

Sunday, October 17, 2010

Page 64: Using Templates to Achieve Awesomer Architecture

two-fer-one

Sunday, October 17, 2010

Page 65: Using Templates to Achieve Awesomer Architecture

#newtwitter’s doing itSunday, October 17, 2010

Page 66: Using Templates to Achieve Awesomer Architecture

node.js is doing itSunday, October 17, 2010

Page 67: Using Templates to Achieve Awesomer Architecture

takes a little doinghave 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

now you’re just showing off.

DEMO NAO PLZ

Sunday, October 17, 2010

Page 68: Using Templates to Achieve Awesomer Architecture

does this template engine come in green?

Sunday, October 17, 2010

Page 69: Using Templates to Achieve Awesomer Architecture

micro-templatesSunday, October 17, 2010

Page 70: Using Templates to Achieve Awesomer Architecture

mustacheSunday, October 17, 2010

Page 71: Using Templates to Achieve Awesomer Architecture

jTemplatesSunday, October 17, 2010

Page 72: Using Templates to Achieve Awesomer Architecture

pureSunday, October 17, 2010

Page 73: Using Templates to Achieve Awesomer Architecture

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

Page 74: Using Templates to Achieve Awesomer Architecture

i appreciate ya!

keep in touch: @garannm / [email protected] code: github.com/garann/templates-example

Sunday, October 17, 2010