Javascript handlebars
W miarę rozwoju internetu język javascript przeżywa dziś swoją drugą młodość. Coraz więcej aplikacji używa go do pobierania danych z serwera bez przeładowywania strony (Ajax). Z pobranych w ten sposób danych zwykle buduje się ciągi znaków i wstawia w odpowiednie miejsca w strukturze strony. Powoduje to często brak odseparowania danych od struktury. W php mamy np. systemy szablonów takie jak phptemplate czy Smarty, a w javascript... już mamy handlebars :) Handlebars to biblioteka napisana w javascript, która pozwala nam tworzyć szablony (na bazie Mustache).
Osadzanie i pierwsze kroki z Handlebars
Szablon handlebars możemy osadzić w dokumencie html pomiędzy znacznikami script z określonym specjalnym atrybutem type="text/x-handlebars-template". Sam szablon wygląda podobnie do zwykłego kodu html z tą różnicą, że wyrażenia hadlebars umieszczamy pomiędzy {{ i }}.<html> <head> <meta charset="UTF-8"> <title>Handlebars demo</title> <script src="http://cloud.github.com/downloads/wycats/handlebars.js/handlebars-1.0.rc.1.js"></script> <script id="result-template" type="text/x-handlebars-template"> <div class="entry"> <h1>{{title}}</h1> <div class="body"> {{body}} </div> </div> </script> <head> <body> <div id="result"></div> <script type="text/javascript"> var source = document.querySelector("#result-template").innerHTML; var template = Handlebars.compile(source); var html = template({title:'Hello', body:'Welcome to my website.'}); document.querySelector("#result").innerHTML = html; </script> </body> </html>Kompilujemy szablon w javascript za pomocą Handlebars.compile. W zmiennej html zapisujemy to co zwrócił nam szablon template z przekazanym mu kontekstem (zestaw danych). Na koniec przekazujemy przetworzony rezultat do diva. Otrzymujemy div wypełniony naszym szablonem (w odpowiednie miejsca zostały wstawione dane z kontekstu).
<div id="result"> <div class="entry"> <h1>Hello</h1> <div class="body"> Welcome to my website. </div> </div> </div>Handlebars domyślnie eskajpuje dane umieszczne pomiędzy {{ i }}. Jeśli nie chcesz aby wartości były eskejpowane użyj {{{ i }}}. Handlebars przykład pierwszy
Dynamiczne szablony
Oczywiście, nie każdy szablon to prosty zestaw kluczy i wartości. Szablon może również być dynamiczny na podstawie wartości mu przekazanych. Spójrzmy na inny przykład, który korzysta z własnego helpera list i instrukcji warunkowej. Helper będzie generował listę html z imionami i nazwiskami. Otrzymuje on jako pierwszy parametr obiekt zawierający osoby, a hash opcji jako drugi parametr. Hash opcji zawiera właściwość fn, którą można wywołać w określonym kontekście tak jakby wywołać normalny szablon Handlebars.<html> <head> <meta charset="UTF-8"> <title>Handlebars demo</title> <script src="http://cloud.github.com/downloads/wycats/handlebars.js/handlebars-1.0.rc.1.js"></script> <script id="result-template" type="text/x-handlebars-template"> {{#if people}} {{#list people}}{{firstName}} {{lastName}}{{/list}} {{else}} <p> No results. </p> {{/if}} </script> </head> <body> <div id="result"></div> <script type="text/javascript"> Handlebars.registerHelper('list', function(items, options) { var out = "<ul>"; for(var i=0, l=items.length; i<l; i++) { out = out + "<li>" + options.fn(items[i]) + "</li>"; } return out + "</ul>"; }); var source = document.querySelector("#result-template").innerHTML; var template = Handlebars.compile(source); var data = { people: [ {firstName: "Yehuda", lastName: "Katz"}, {firstName: "Carl", lastName: "Lerche"}, {firstName: "Alan", lastName: "Johnson"} ] }; var html = template(data); document.querySelector("#result").innerHTML = html; </script> </body> </html>Wynikiem powyższego kodu będzie lista:
<ul> <li>Yehuda Katz</li> <li>Carl Lerche</li> <li>Alan Johnson</li> </ul>Handlebars przykład drugi
Oprócz konstrukcji if else istnieją np. jeszcze konstrukcje unless (odwrotność ifa - blok będzie wyrenderowany jeśli wyrażenie zwróci false) czy each (iterowanie przez listę).
<div> {{#unless exp}} <p>WARNING: exp return false!</p> {{/unless}} </div>Zastosowanie konstrukcji each:
<ul id="list"> {{#each people}} <li>{{this}}</li> {{/each}} </ul>Przykładowy kontekst:
{ people: [ "Yehuda Katz", "Alan Johnson", "Charles Jolley" ] }Rezultat:
<ul id="list"> <li>Yehuda Katz</li> <li>Alan Johnson</li> <li>Charles Jolley</li> </ul>Po więcej przykładów i informacji odsyłam na stronę handlebarsjs.