SlideShare a Scribd company logo
1 of 74
Download to read offline
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

More Related Content

What's hot

Kick start with j query
Kick start with j queryKick start with j query
Kick start with j query
Md. Ziaul Haq
 
jQuery%20on%20Rails%20Presentation
jQuery%20on%20Rails%20PresentationjQuery%20on%20Rails%20Presentation
jQuery%20on%20Rails%20Presentation
guestcf600a
 
ZendCon2010 Doctrine MongoDB ODM
ZendCon2010 Doctrine MongoDB ODMZendCon2010 Doctrine MongoDB ODM
ZendCon2010 Doctrine MongoDB ODM
Jonathan Wage
 

What's hot (17)

Beyond the DOM: Sane Structure for JS Apps
Beyond the DOM: Sane Structure for JS AppsBeyond the DOM: Sane Structure for JS Apps
Beyond the DOM: Sane Structure for JS Apps
 
Learning jQuery in 30 minutes
Learning jQuery in 30 minutesLearning jQuery in 30 minutes
Learning jQuery in 30 minutes
 
Kick start with j query
Kick start with j queryKick start with j query
Kick start with j query
 
The jQuery Divide
The jQuery DivideThe jQuery Divide
The jQuery Divide
 
jQuery Basic API
jQuery Basic APIjQuery Basic API
jQuery Basic API
 
jQuery%20on%20Rails%20Presentation
jQuery%20on%20Rails%20PresentationjQuery%20on%20Rails%20Presentation
jQuery%20on%20Rails%20Presentation
 
Desenvolvendo Aplicativos Sociais com Rails 3
Desenvolvendo Aplicativos Sociais com Rails 3Desenvolvendo Aplicativos Sociais com Rails 3
Desenvolvendo Aplicativos Sociais com Rails 3
 
jQuery - Introdução
jQuery - IntroduçãojQuery - Introdução
jQuery - Introdução
 
Doctrine MongoDB Object Document Mapper
Doctrine MongoDB Object Document MapperDoctrine MongoDB Object Document Mapper
Doctrine MongoDB Object Document Mapper
 
PhoneGap: Local Storage
PhoneGap: Local StoragePhoneGap: Local Storage
PhoneGap: Local Storage
 
Prototype & jQuery
Prototype & jQueryPrototype & jQuery
Prototype & jQuery
 
ZendCon2010 Doctrine MongoDB ODM
ZendCon2010 Doctrine MongoDB ODMZendCon2010 Doctrine MongoDB ODM
ZendCon2010 Doctrine MongoDB ODM
 
jQuery Essentials
jQuery EssentialsjQuery Essentials
jQuery Essentials
 
Symfony2 from the Trenches
Symfony2 from the TrenchesSymfony2 from the Trenches
Symfony2 from the Trenches
 
Jquery-overview
Jquery-overviewJquery-overview
Jquery-overview
 
An Introduction to Jquery
An Introduction to JqueryAn Introduction to Jquery
An Introduction to Jquery
 
jQuery
jQueryjQuery
jQuery
 

Viewers also liked

Тайм-менеджмент для иррационалов: как неорганизованным людям управлять делами
Тайм-менеджмент для иррационалов: как неорганизованным людям управлять деламиТайм-менеджмент для иррационалов: как неорганизованным людям управлять делами
Тайм-менеджмент для иррационалов: как неорганизованным людям управлять делами
Artem Polyanskiy
 
Homepage Designs of Computer Companies
Homepage Designs of Computer CompaniesHomepage Designs of Computer Companies
Homepage Designs of Computer Companies
Charlie Hoehn
 
Videnskabsteori, teori og metode, rennison
Videnskabsteori, teori og metode, rennisonVidenskabsteori, teori og metode, rennison
Videnskabsteori, teori og metode, rennison
Betina Rennison
 
«Организация Frontend-разработки на крупном проекте» — Дмитрий Кузнецов
«Организация Frontend-разработки на крупном проекте» — Дмитрий Кузнецов«Организация Frontend-разработки на крупном проекте» — Дмитрий Кузнецов
«Организация Frontend-разработки на крупном проекте» — Дмитрий Кузнецов
2ГИС Технологии
 

Viewers also liked (19)

Современный фронтенд за 30 минут.
Современный фронтенд за 30 минут.Современный фронтенд за 30 минут.
Современный фронтенд за 30 минут.
 
SMACSS - масштабируемая модульная архитектура css
SMACSS - масштабируемая модульная архитектура cssSMACSS - масштабируемая модульная архитектура css
SMACSS - масштабируемая модульная архитектура css
 
Тайм-менеджмент для иррационалов: как неорганизованным людям управлять делами
Тайм-менеджмент для иррационалов: как неорганизованным людям управлять деламиТайм-менеджмент для иррационалов: как неорганизованным людям управлять делами
Тайм-менеджмент для иррационалов: как неорганизованным людям управлять делами
 
National mosque
National mosqueNational mosque
National mosque
 
Бэкенд, фронтенд — всё смешалось (nodkz)
Бэкенд, фронтенд — всё смешалось (nodkz)Бэкенд, фронтенд — всё смешалось (nodkz)
Бэкенд, фронтенд — всё смешалось (nodkz)
 
Islamic Influences on American Architecture
Islamic Influences on American ArchitectureIslamic Influences on American Architecture
Islamic Influences on American Architecture
 
Homepage Designs of Computer Companies
Homepage Designs of Computer CompaniesHomepage Designs of Computer Companies
Homepage Designs of Computer Companies
 
Mosque architecture of Bangladesh
Mosque architecture of BangladeshMosque architecture of Bangladesh
Mosque architecture of Bangladesh
 
Architecture of mosque
Architecture of mosqueArchitecture of mosque
Architecture of mosque
 
Architecture
ArchitectureArchitecture
Architecture
 
Videnskabsteori, teori og metode, rennison
Videnskabsteori, teori og metode, rennisonVidenskabsteori, teori og metode, rennison
Videnskabsteori, teori og metode, rennison
 
Getting Started With Django
Getting Started With DjangoGetting Started With Django
Getting Started With Django
 
«Организация Frontend-разработки на крупном проекте» — Дмитрий Кузнецов
«Организация Frontend-разработки на крупном проекте» — Дмитрий Кузнецов«Организация Frontend-разработки на крупном проекте» — Дмитрий Кузнецов
«Организация Frontend-разработки на крупном проекте» — Дмитрий Кузнецов
 
Flexbox - верстка без float'ов by Dmitry Radyno
Flexbox - верстка без float'ов by Dmitry RadynoFlexbox - верстка без float'ов by Dmitry Radyno
Flexbox - верстка без float'ов by Dmitry Radyno
 
Mosque typology AND MOSQUE architecture in Malaysia
Mosque typology AND MOSQUE architecture in MalaysiaMosque typology AND MOSQUE architecture in Malaysia
Mosque typology AND MOSQUE architecture in Malaysia
 
Mughal Architecture [fort, mosque[masjid], tomb
Mughal Architecture  [fort, mosque[masjid], tombMughal Architecture  [fort, mosque[masjid], tomb
Mughal Architecture [fort, mosque[masjid], tomb
 
Perkembangan arsitektur masjid
Perkembangan arsitektur masjidPerkembangan arsitektur masjid
Perkembangan arsitektur masjid
 
15 Years of Apple's Homepage
15 Years of Apple's Homepage15 Years of Apple's Homepage
15 Years of Apple's Homepage
 
Oboljenja organa za varenje
Oboljenja organa za varenjeOboljenja organa za varenje
Oboljenja organa za varenje
 

Similar to Using Templates to Achieve Awesomer Architecture

Dominion Enterprises _H@&lt;k@th0n_
Dominion Enterprises _H@&lt;k@th0n_Dominion Enterprises _H@&lt;k@th0n_
Dominion Enterprises _H@&lt;k@th0n_
Ken Collins
 
C A S Sample Php
C A S Sample PhpC A S Sample Php
C A S Sample Php
JH Lee
 
Document-Oriented Databases: Couchdb Primer
Document-Oriented Databases: Couchdb PrimerDocument-Oriented Databases: Couchdb Primer
Document-Oriented Databases: Couchdb Primer
jsiarto
 

Similar to Using Templates to Achieve Awesomer Architecture (20)

D-Talk: What's awesome about Ruby 2.x and Rails 4
D-Talk: What's awesome about Ruby 2.x and Rails 4D-Talk: What's awesome about Ruby 2.x and Rails 4
D-Talk: What's awesome about Ruby 2.x and Rails 4
 
elasticsearch basics workshop
elasticsearch basics workshopelasticsearch basics workshop
elasticsearch basics workshop
 
WordPress Front End Optimizations
WordPress Front End OptimizationsWordPress Front End Optimizations
WordPress Front End Optimizations
 
XML - State of the Art
XML - State of the ArtXML - State of the Art
XML - State of the Art
 
DB2 Native XML
DB2 Native XMLDB2 Native XML
DB2 Native XML
 
Dominion Enterprises _H@&lt;k@th0n_
Dominion Enterprises _H@&lt;k@th0n_Dominion Enterprises _H@&lt;k@th0n_
Dominion Enterprises _H@&lt;k@th0n_
 
XSLT
XSLTXSLT
XSLT
 
PostgreSQL's Secret NoSQL Superpowers
PostgreSQL's Secret NoSQL SuperpowersPostgreSQL's Secret NoSQL Superpowers
PostgreSQL's Secret NoSQL Superpowers
 
Unfiltered Unveiled
Unfiltered UnveiledUnfiltered Unveiled
Unfiltered Unveiled
 
dojo.things()
dojo.things()dojo.things()
dojo.things()
 
Introduction to jQuery
Introduction to jQueryIntroduction to jQuery
Introduction to jQuery
 
Jquery 2
Jquery 2Jquery 2
Jquery 2
 
Handlebars
HandlebarsHandlebars
Handlebars
 
C A S Sample Php
C A S Sample PhpC A S Sample Php
C A S Sample Php
 
Jquery
JqueryJquery
Jquery
 
ES6 is Nigh
ES6 is NighES6 is Nigh
ES6 is Nigh
 
Metaprogramming
MetaprogrammingMetaprogramming
Metaprogramming
 
Ch3(working with file)
Ch3(working with file)Ch3(working with file)
Ch3(working with file)
 
Designers Guide To jQuery
Designers Guide To jQueryDesigners Guide To jQuery
Designers Guide To jQuery
 
Document-Oriented Databases: Couchdb Primer
Document-Oriented Databases: Couchdb PrimerDocument-Oriented Databases: Couchdb Primer
Document-Oriented Databases: Couchdb Primer
 

Recently uploaded

Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
Joaquim Jorge
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
vu2urc
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
Earley Information Science
 

Recently uploaded (20)

Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonets
 
Evaluating the top large language models.pdf
Evaluating the top large language models.pdfEvaluating the top large language models.pdf
Evaluating the top large language models.pdf
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
 
GenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdfGenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdf
 

Using Templates to Achieve Awesomer Architecture

  • 1. using templates to achieve AWESOMER architecture Sunday, October 17, 2010
  • 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. ask me how i reduced 12k lines of js to 4k Sunday, October 17, 2010
  • 4. get that now http://github.com/jquery/jquery-tmpl Sunday, October 17, 2010
  • 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. 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. 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. 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. that’s not an architecture #thatsaproblem Sunday, October 17, 2010
  • 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. pros and cons no templates templates Sunday, October 17, 2010
  • 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. 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
  • 21. properties ${bandName} is the world’s greatest band. Everyone loves {{= bandName}}. Sunday, October 17, 2010
  • 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. 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. 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. 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. 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. 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. 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. how do they work? Sunday, October 17, 2010
  • 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. $.tmpl String immediately parsed and evaluated Tags translated to expressions Return a jQuery object Sunday, October 17, 2010
  • 32. compiling $.template(“veryShortTmpl”,”<b>${name}</b>”); $(“#stuff-tmpl”).template(“wickedCoolTmpl”); Sunday, October 17, 2010
  • 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. 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. $.tmplItem tmplItem has additional functions and properties nodes, parent, html, nest, wrap Functions remain available to object in DOM Sunday, October 17, 2010
  • 37. weak $(“#some-tmpl”).tmpl(data).appendTo(“#thing”); $(“a.childOfThing”).click(function(e) { e.preventDefault(); doMoreStuff(); }); Sunday, October 17, 2010
  • 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. 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. when the only tool you have is a hammer.. oh wait you have CSS Sunday, October 17, 2010
  • 41. awesome $(“#some-tmpl”).tmpl(data).appendTo(“#thing”); $(“#childOfThing”).tmplItem().tmpl = $(“#state-two-tmpl”).template(); Sunday, October 17, 2010
  • 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. 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. fast, good, cheap: pick two and a half Sunday, October 17, 2010
  • 45. faster-ish templates break up the family separate pattern templates from interface templates Always Be Compiling templates = functions Sunday, October 17, 2010
  • 46. stop sending html Sunday, October 17, 2010
  • 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. 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. inline edit $(“#anEditButton”).live(“click”,function() { $(“#thisGuysParent”) .tmplItem() .tmpl = $(“#edit-mode-tmpl”).template(); }); Sunday, October 17, 2010
  • 50. yo dawg we heard you like plugins Sunday, October 17, 2010
  • 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. AWESOMER! $.fn.myPlugin = function(options) { this.html($.tmpl(“myTemplate”,options)); ... return this; } Sunday, October 17, 2010
  • 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. AWESOMER! $.fn.myPlugin.update = function(newOpts) { this.tmplItem().data = newOpts; ... } Sunday, October 17, 2010
  • 55. AWESOMER plugins No more DOM manipulation Don’t have to require a template engine * Sexy updates and redraws Sunday, October 17, 2010
  • 56. where do templates come from? Sunday, October 17, 2010
  • 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. 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. 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. 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. 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. what about clients without js? Sunday, October 17, 2010
  • 63. noscripts srsly? clientside templates on the serverside Sunday, October 17, 2010
  • 66. node.js is doing it Sunday, October 17, 2010
  • 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. does this template engine come in green? Sunday, October 17, 2010
  • 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. i appreciate ya! keep in touch: @garannm / garann@gmail.com demo code: github.com/garann/templates-example Sunday, October 17, 2010