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). Handlebars

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.