using templates to achieve awesomer architecture

Post on 29-Oct-2014

33 Views

Category:

Technology

0 Downloads

Preview:

Click to see full reader

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

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 nowhttp://github.com/jquery/jquery-tmpl

Sunday, October 17, 2010

alternatives?

Sunday, October 17, 2010

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

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

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

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 templatesSunday, October 17, 2010

performanceSunday, October 17, 2010

DRYSunday, October 17, 2010

minimize dom manipulationSunday, October 17, 2010

maintainabilitySunday, October 17, 2010

lazy loadingSunday, October 17, 2010

<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

<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

exciting syntax!

Sunday, October 17, 2010

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

Everyone loves {{= bandName}}.

properties

Sunday, October 17, 2010

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

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

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

<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

<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

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

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

how do they work?

Sunday, October 17, 2010

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

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

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

rendering

Sunday, October 17, 2010

$.tmplString immediately parsed and evaluated

Tags translated to expressions

Return a jQuery object

Sunday, October 17, 2010

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

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

compiling

Sunday, October 17, 2010

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

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

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

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

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

});

weak

Sunday, October 17, 2010

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

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

when the only tool you have is a hammer..

oh wait you have CSS

Sunday, October 17, 2010

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

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

awesome

Sunday, October 17, 2010

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

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

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

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

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

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

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

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

});

});

pagination

Sunday, October 17, 2010

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

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

});

inline edit

Sunday, October 17, 2010

yo dawg we heard you like plugins

Sunday, October 17, 2010

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

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

}

AWESOMER!

Sunday, October 17, 2010

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

}

weak

Sunday, October 17, 2010

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

}

AWESOMER!

Sunday, October 17, 2010

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

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

<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

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

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

noscriptssrsly?

clientside templates on the serverside

Sunday, October 17, 2010

two-fer-one

Sunday, October 17, 2010

#newtwitter’s doing itSunday, October 17, 2010

node.js is doing itSunday, October 17, 2010

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

does this template engine come in green?

Sunday, October 17, 2010

micro-templatesSunday, October 17, 2010

mustacheSunday, October 17, 2010

jTemplatesSunday, October 17, 2010

pureSunday, 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.comdemo code: github.com/garann/templates-example

Sunday, October 17, 2010

top related