Como são os layouts Handlebars

Estudo do sistema de layouts Javascript Handlebars, análise das possibilidades dos layouts, sintaxe, estruturas de controle, etc.

Por Eduard Tomás - Tradução CRV


Publicado em: 19/6/13
Valorize este artigo:
 
Nos artigos anteriores do Manual de Handlebars pudemos conhecer o que nos oferecem os sistemas de layouts Javascript e como dar os primeiros passos com Handlebars. Agora vamos estudar mais de perto esta biblioteca de layouts Javascript para entender seu funcionamento.

Começamos por observar nos layouts os blocos delimitados por {{ }} duas chaves de inicio e duas chaves de fechamento. Essa forma de abrir e fechar um bloco no layout é o que dá nome à sintaxe que utiliza "Mustache".
 

Inserir valores nos layouts

Os valores simples se inserem no código HTML de um layout começando por {{ e terminando por }}.

{{valor}}

Embora também se possam usar três chaves ao mesmo tempo, em cujo o caso não escapará o código HTML que haja no valor.

{{{valor}}}
 

Inserir expressões de bloco

Os blocos permitem escrever algumas estruturas de controle simples, como loopings. Sua sintaxe é similar aos dados, mas utilizamos ademais um"#" para abrir o bloco e "/" para terminá-lo.

{{# each Beers}} ... {{/each}}

Isto nos vai permitir executar templates em um contexto distinto do original. Mais tarde o veremos devidamente. Entre os blocos disponíveis temos:

  • each {{# each expresion}} Itera sobre cada elemento de expressão e gera o template associado. O elemento pelo que se itera passa a ser o novo contexto.
  • if {{if expresion}} Se expressão retorna false, undefined, "", null ou [] NÃO renderiza o bloco. Admite {{else}}.
  • Unless {{#unless expresion}} isto, ao contrario de if, renderiza o bloco se expressão retorna false, undefined, null, "" ou [].
As propriedades do objeto JSON são perfeitamente navegáveis, acessando o nome {{name}}, mas também compostas em notação de objeto, como {{author.name}}. Inclusive podemos fazer o passo contrario e ir para o contexto pai com {{../name}}, sendo "name" uma propriedade encontrada no contexto pai.
 

Helpers em Handlebars

Também temos disponível a figura dos "Helpers", que nos ajudam a registrar nossas próprias funções para fazer coisas mais específicas e repetitivas. Podemos entender os helpers como uma extensão do próprio sistema de layouts Handlebars, e são como funções que podem ser referenciadas desde qualquer template. Permitem executar código para dar maior funcionalidade aos layouts e assim modificar/combinar dados do contexto.

{{fullName author}} invoca o helper fullName passando a ele a propriedade author do contexto.

Se registram e se criam helpers próprios com Handlebars.registerHelper(), com código como o seguinte:

Handlebars.registerHelper('Italize', function (value) {
return new Handlebars.SafeString("<em>" + value + "</em>");
})

Para criar um helper sempre usamos o método "registerHelper", indicando como primeiro parâmetro o nome do helper, seguido de um segundo parâmetro que é a função do helper propriamente dito. Nessa função recebemos ademais dados que podemos usar dentro do código do helper e cujos valores lhe passamos a partir do código do layout.

Nota: o método "SafeString()" é de Handlebars e o que faz é dizer à biblioteca que o código HTML que colocamos é seguro e que não necessita escapá-lo para que se renderizem as etiquetas que contém. Se não retorno por meio da função SafeString(), handlebars entenderia que as etiquetas são texto e as mostraria escapadas, de modo que seriam vistas na página.

Por exemplo, o helper anterior chamado "Italize" poderia ser invocado a partir do layout com o seguinte código:

{{# each Beers}}
Name: {{Name}} - Abv: {{Italize Abv}} <br />
{{/each}}

Nota: neste caso o helper Italize simplesmente muda para cursiva um texto e não seria muito necessário implementar por meio de um helper. Podería nos ajudar se mais adiante queremos mostrar todos os "Italize" de uma maneira especial e que só tenhamos que modificar para isso o código do helper, porém geralmente o usaremos para alguma estrutura um pouco mais complexa.

Podemos ver o código fonte do seguinte exemplo de Handlebars, que faz uso do helper anterior.

 <!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Beer List</title>
<link href="Site.css" rel="stylesheet" />
<script src="handlebars.js"></script>
<script src="jquery-2.0.0.min.js"></script>

<script type="text/x-handlebars-template" id="template">
{{# each Beers}}
Name: {{Name}} - Abv: {{Italize Abv}} <br />
{{/each}}

</script>
</head>
<body>
<div id="content" style="display:none;">
<strong>Our Beers...</strong><br/>

</div>
<script type="text/javascript">

(function() {
Handlebars.registerHelper('Italize', function (value) {
return new Handlebars.SafeString(
"<em>" + value + "</em>");
});
})();


$(function() {
var stemplate = $("#template").html();
var tmpl = Handlebars.compile(stemplate);
var xhr = $.ajax({
url: '/api/Beers'
});

xhr.done(function (data) {
var ctx = {};
ctx.Beers = data;
var html = tmpl(ctx);
$("#content").append(html);
$("#content").show();
});
});

</script>

</body>
</html>

Se você observar o código fonte do exemplo do artigo anterior deste manual, vai achar que o Javascript que usamos para compilar o layout, invocar obackend para trazer por AJAX o JSON e executar o layout, é muito parecido. Realmente isto é normal, porque todo esse processo não variará apenas nos distintos exemplos que façamos. O que você perceberá que varia são os layouts e os helpers que possamos construir.

Lembre que o JSON é o mesmo em todos os exercícios que realizamos sobre Handlebars e que você pode vê-lo em: www.desarrolloweb.com/articulos/ejemplos/handlebars/Beers.json
 

Exemplo com bloco IF

Agora podemos ver como seria um layout que tem um bloco "if", para mostrar somente os conteúdos que tenham algumas características.

{{# each Beers}}
{{# if Favorite}}
Name: {{Name}} - Abv: {{Italize Abv}} <br />
{{/if}}
{{/each}}

Com isto conseguimos que só se imprimam aquelas cervejas que foram marcadas como "Favorite".
 

Exemplo de helper mais elaborado

No nosso trabalho com helpers encontraremos quase sempre casos mais claros onde o uso destas funções nos pouparão mais código. Por exemplo, a partir de um booleano podemos mostrar um ícone que simbolize certo estado.

Handlebars.registerHelper('ShowStar', function (value) {
if (value) {
return new Handlebars.SafeString("<img src='favorite.png' alt='i love this beer!'/>");
} else
return "";
});

Neste Helper se usa o parâmetro "value" para carregar dados que será um booleano no objeto JSON. Em caso positivo mostra uma imagem de um ícone e em caso negativo não mostra nada.

Poderíamos usá-lo a partir de um layout como este:

{{# each Beers}}
Name: {{Name}} - Abv: {{Italize Abv}} {{ShowStar Favorite}}
<br />
{{/each}}

Outra possibilidade interessante é que poderíamos ter, por exemplo, um helper que convertesse um nome de usuário Twitter em um link em seu perfil.

Handlebars.registerHelper('Twitter', function (value) {
return new Handlebars.SafeString('<a href="http://twitter.com/' + value.substr(1) + '">' + value + '</a>');
});

Observe que este helper já tem certa complexidade, porque fazemos um tratamento Javascript a "value", para tirar a "@" de um usuário Twitter. Para transformar um dado usamos o método de String "substr()", com o que demonstramos que quando se está programando um helper não somente se podem mostrar dados de nosso jSON do mesmo modo, mas também se podem transformar antes de apresentar na página.

Poderíamos usá-lo já a partir de um layout como este:

<ul>
{{# each Beers}}
<li>Name: {{Name}} - Abv: {{Italize Abv}} {{ShowStar Favorite}}
<p>Drinked by: {{Twitter LastCheckin.Drinker}} at {{LastCheckin.When}}</p>
</li>
{{/each}}
</ul>

 






Usuários :    login / registro

Manuais relacionados
Categorias relacionadas
O autor

Home | Sobre nós | Copyright | Anuncie | Entrar em contato