Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Manual Handlebars PDF
Manual Handlebars PDF
http://desarrolloweb.com/manuales/manual-handlebars.html Página 1 de 25
Manual de Handlebars
Los sistemas de plantillas son muy importantes, porque nos permiten separar el código por
responsabilidades y crear la salida de las aplicaciones de una manera sencilla, manteniendo el
código HTML separado del código Javascript. En este manual aprenderás a usar el sistema de
plantillas Javascript tanto en el lado del cliente como en el lado del servidor con NodeJS.
Puedes usar Handlebars junto con cualquier librería de manipulación del DOM como jQuery, o
simplemente con Javascript plano. También puedes usarla en el lado del servidor, con NodeJS
en el caso que tengas que generar salida formateada desde ese lenguaje.
http://desarrolloweb.com/manuales/manual-handlebars.html Página 2 de 25
Manual de Handlebars
Las siguientes personas han participado como autores escribiendo artículos de este manual.
Eduard Tomàs
http://desarrolloweb.com/manuales/manual-handlebars.html Página 3 de 25
Manual de Handlebars
Qué son los motores de plantillas y cómo nos pueden facilitar la vida a los
programadores en Javascript. Ejemplos de librerías que implementan las
plantillas.
Si pensabas que las plantillas eran algo ligado al back-end es que todavía tienes bastante que
explorar en cuanto a desarrollo del lado del cliente. En este artículo pretendemos explicar qué
son las plantillas Javascript, de modo que podamos entender su utilidad y cómo pueden llegar
a ser esenciales para una programación front-end sencilla y mantenible.
Creo que lo mejor para entender la necesidad de usar plantillas en Javascript es haberse visto
en el quebradero de cabeza en que nos encontramos cuando queremos generar dinámicamente
elementos en el DOM de la página web. Así que comenzaremos explicando sus ventajas con un
ejemplo en el que podemos habernos encontrado.
¿No sería mejor mantener esas estructuras en HTML plano y simplemente llamar a una
función que nos cargue los datos enviados dentro del código HTML? Pues eso es básicamente
lo que conseguimos con las plantillas.
No hay mucho secreto. Nuestra plantilla tendría un aspecto como este código HTML:
<div class="estructura">
http://desarrolloweb.com/manuales/manual-handlebars.html Página 4 de 25
Manual de Handlebars
<h1>{{titulo}}</h1>
<div class="cuerpo">
{{cuerpo}}
</div>
</div>
Nota: Esa plantilla está basada en la sintaxis Mustache Templates, que utiliza la librería
Handlebars JS.
Como ves, hay bloques de contenido que se pueden rellenar con datos variables, son los
{{titulo}} y {{body}}. Pues nada más tendríamos que invocar a esa plantilla enviando los datos
que queremos cargar en el HTML y nos devolverá el código HTML resultante, ya con los datos
dentro de las etiquetas, en una cadena que podríamos insertar en el DOM de una manera
sencillísima con nuestra librería Javascript preferida, ya sea jQuery o con cualquier otra.
Nos queda en el aire ver cómo sería el sistema para ejecutar la plantilla, pero realmente esa
implementación depende del sistema de plantillas que estés utilizando, aunque generalmente
será algo tan sencillo como ejecutar un método o una función.
Nota: Qué tal, ¿se entiende bien la estructura del HTML de la plantilla a simple vista? Si
todavía no te resulta obvio lo útil de mantener las plantillas en HTML, echa un vistazo al
código Javascript siguiente. Algo como esto sería lo que tendríamos que escribir usando
jQuery para crear esa estructura HTML como la de la plantilla anterior:
$("<div></div>")
.addClass("estructura")
.append($("<div></div>")
.html(cuerpo)
.addClass("cuerpo"))
.appendTo("body");
Como se puede ver, construir estructuras DOM desde jQuery no es muy práctico, y aunque
se pueda hacer perfectamente, no resulta cómodo.
http://desarrolloweb.com/manuales/manual-handlebars.html Página 5 de 25
Manual de Handlebars
Los sistemas de plantillas son además compañeros inseparables de algunas librerías avanzadas
Javascript que nos traen paradigmas de desarrollo diferentes, como los MVVM, que sería algo
parecido al MVC pero para desarrollo en el cliente. En los últimos meses se ha hablado mucho
de AngularJS, que ya viene con su propio sistema de plantillas. Pero otras, como por ejemplo
Backbone no implementan su propio sistema de templating, de modo que cualquiera de las
siguientes librerías Javascript te vendrá ideal.
Handlebars:
Un motor de plantillas para Javascript que implementa la sintaxis Mustache Templates y que
provee de funcionalidades adicionales para su compilación y procesamiento.
handlebarsjs.com
Underscore.js:
Una librería Javascript que provee un gran abanico de funcionalidades diversas y útiles para
cualquier proyecto. Entre otras cosas podrás generar y usar plantillas Javascript.
underscorejs.org
Pure:
beebole.com/pure
http://desarrolloweb.com/manuales/manual-handlebars.html Página 6 de 25
Manual de Handlebars
jsrender:
github.com/BorisMoore/jsrender
En general, podríamos nombrar algunas otras librerías, pero estas son las que actualmente
mejor pinta tienen. En la actualidad todo depende de tus preferencias, ya que en Javascript
existen decenas de librerías para resolver las mismas cosas. Todo será ver la que al final acaba
teniendo mayor penetración.
http://desarrolloweb.com/manuales/manual-handlebars.html Página 7 de 25
Manual de Handlebars
En este artículo te vamos a poner manos a la obra con HandlebarsJS y ahorrarte muchas líneas
de código Javascript o jQuery, que puede llegar a ser bastante enrevesado y de difícil
mantenimiento. Si te dedicas a la programación front-end, debes invertir una rato con
nosotros leyendo estas líneas.
Nota: este artículo está realizado a raíz del programa #jQueryIO emitido recientemente, en
el que Eduard Tomàs nos presentó Handlebars y nos mostró varios ejemplos de su uso. No
es una transcripción directa, pero todas las explicaciones están basadas en las que nos
ofreció Edu. Los ejemplos que vamos a ver son los que el propio ponente nos presentó
durante su exposición.
El primer paso para entender qué es Handlebars y por qué nos resultará de utilidad es
entender qué son los sistemas de plantillas de Javascript.
http://desarrolloweb.com/manuales/manual-handlebars.html Página 8 de 25
Manual de Handlebars
Además, en las plantillas podrás tener estructuras sencillas como bloques condicionales,
iteradores que recorran colecciones, etc. Veremos que todo ello es sencillo porque Handlebars
es una librería con funciones limitadas, útiles, pero bastante restringidas al propósito único de
generar HTML a partir de objetos JSON.
Cargar una plantilla, que no es más que un código HTML mezclado con unos sencillos
elementos de control
Compilar la plantilla, que nos permite convertirlo en una función JS
Ejecutar la plantilla para obtener la cadena HTML a partir del JSON
Insertar en el DOM el código HTML resultante de ejecutar el template, usando jQuery o
nuestra librería preferida
Nota: Se debe pensar en que, si se intenta ejecutar un template Handlebars con Javascript
se encontrará con un error, ya que el template está escrito en código HTML. Por ello se
coloca un type a la etiqueta Script que el navegador no conozca, de modo que nos
aseguremos que no va a intentar ejecutarlo.
La otra opción es usar una llamada a AJAX para traerte los templates, con la única limitación
que se debe sincronizar el retorno de la llamada con la compilación y ejecución de los
templates. En otras palabras, debemos esperar que la llamada a AJAX para traerte el template
se ha producido con éxito para poder compilar llas plantillas que vamos a usar en nuestra
página.
Compilar un template:
En Handlebars tenemos que hacer un paso previo antes de poder ejecutar un template, que es
compilarlo. Es algo muy simple. Llamamos a Handlebars.compile() enviándole como
parámetro el texto de nuestra plantilla. El resultado de esto es una función, que es la que
tendremos que invocar para ejecutarla.
La variable "stemplate" es la cadena con el contenido del template. Finalmente, una vez
compilada, en la variable que recibimos como retorno, que hemos llamado tmpl, tendrás la
función de la plantilla.
http://desarrolloweb.com/manuales/manual-handlebars.html Página 9 de 25
Manual de Handlebars
Obtenemos como respuesta de la función del template un código HTML listo para ser
insertado en el DOM.
Ese HTML es el que podremos usar más tarde para insertar en la página.
Nota: Los templates los compilamos una única vez y los ejecutamos tantas veces como
queramos. El proceso costoso en tiempo de ejecución es compilar los templates. Una vez se
ha hecho ejecutar el template para producir el HTML es un proceso rápido que podemos
realizar tantas veces como necesitemos sin tener que sufrir por el rendimiento de la
aplicación.
{{/each}}
</script>
Luego explicaremos las estructuras de control para las plantillas, pero podrás apreciar aquí
una iteración en la que se recorre una estructura llamada "Beers" y se va mostrando su dato
"Name".
Nota: aquí ves el método html() de jQuery, pero no quiere decir que Handlebars use
jQuery de manera única, lo podemos usar con cualquier librería que deseemos. A lo largo
de este ejemplo se usa jQuery diversas veces.
http://desarrolloweb.com/manuales/manual-handlebars.html Página 10 de 25
Manual de Handlebars
Ahora podríamos traernos nuestro JSON por medio de AJAX. De nuevo, usaremos la librería
que deseemos. Con la cadena JSON recibida simplemente le aplicamos un contexto:
html = tmpl(ctx);
$("#content").append(html);
$("#content").show();
[{"Name":"Estrella","Brewery":"Damm","Style":"Euro Lager","Abv":"5.4","Ibu":"25","Favorite":false,"LastCheckin":{"When":"24/04/2013 -
20:00:01","Drinker":"@eiximenis"}},
{"Name":"Voll Damm","Brewery":"Damm","Style":"Bock","Abv":"7.2","Ibu":"40","Favorite":false,"LastCheckin":{"When":"24/04/2013 -
21:00:01","Drinker":"@CKGrafico"}},
22:00:01","Drinker":"@midesweb"}},
23:00:01","Drinker":"@eiximenis"}}]
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Beer List</title>
<script src="handlebars.js"></script>
http://desarrolloweb.com/manuales/manual-handlebars.html Página 11 de 25
Manual de Handlebars
<script src="jquery-2.0.0.min.js"></script>
{{/each}}
</script>
</head>
<body>
<strong>Our Beers...</strong><br/>
</div>
<script type="text/javascript">
$(function() {
url: '/api/Beers'
});
xhr.done(function (data) {
ctx.Beers = data;
$("#content").append(html);
$("#content").show();
});
});
</script>
</body>
</html>
http://desarrolloweb.com/manuales/manual-handlebars.html Página 12 de 25
Manual de Handlebars
En los artículos anteriores del Manual de Handlebars hemos podido conocer qué nos ofrecen
los sistemas de plantillas Javascript y cómo dar los primeros pasos con Handlebars. Ahora
vamos a estudiar más de cerca esta librería de plantillas Javascript para entender su
funcionamiento.
Comenzamos por observar en las plantillas los bloques delimitados por {{ }} dos llaves de
inicio y dos llaves de cierre. Esa forma de abrir y cerrar un bloque en la plantilla es la que da
nombre a la sintaxis que utiliza "Mustache".
{{valor}}
Aunque también se pueden usar tres llaves a la vez, en cuyo caso no escapará el código HTML
que haya en el valor.
{{{valor}}}
http://desarrolloweb.com/manuales/manual-handlebars.html Página 13 de 25
Manual de Handlebars
terminarlo.
Esto nos va a permitir ejecutar templates en un contexto distinto al del original. Luego lo
veremos exactamente. Entre los bloques disponibles tememos:
each {{# each expresion}} Itera sobre cada elemento de expresión y genera el template
asociado. El elemento por el que se itera pasa a ser el nuevo contexto.
if {{if expresion}} Si expresion devuelve false, undefined, "", null o [] NO renderiza el
bloque. Admite {{else}}.
Unless {{#unless expresion}} esto, al contrario que if, renderiza el bloque si expresion
devuelve false, undefined, null, "" o [].
Las propiedades del objeto JSON son perfectamente navegables, accediendo al nombre
{{name}}, pero también a compuestas en notación de objeto, como {{author.name}}. Incluso
podemos hacer el paso contrario e irnos al contexto padre con {{../name}}, siendo "name" una
propiedad encontrada en el contexto padre.
Helpers en Handlebars
También tenemos disponible la figura de los "Helpers", que nos ayudan a registrar nuestras
propias funciones para hacer cosas más concretas y repetitivas. Podemos entender los helpers
como una extensión del propio sistema de plantillas Handlebars, y son como funciones que se
pueden referenciar desde cualquier template. Permiten ejecutar código para dar mayor
funcionalidad a las plantillas y así modificar/combinar datos del contexto.
{{fullName author}} invoca al helper fullName pasándole la propiedad author del contexto.
})
Para crear un helper siempre usamos el método "registerHelper", indicando como primer
parámetro el nombre del helper, seguido de un segundo parámetro que es la función del helper
propiamente dicho. En esa función recibimos además datos que podemos usar dentro del
código del helper y cuyos valores le pasamos desde el código de la plantilla.
http://desarrolloweb.com/manuales/manual-handlebars.html Página 14 de 25
Manual de Handlebars
Por ejemplo, el helper anterior llamado "Italize" se podría invocar desde la plantilla con el
siguiente código:
{{/each}}
Nota: en este caso el helper Italize simplemente cambia a cursiva un texto y no sería muy
necesario implementar por medio de un helper. Podría venirnos bien si más adelante todos
los "Italize" los queremos mostrar de una manera especial y que solo tengamos que
modificar para ello el código del helper, pero generalmente lo usaremos para alguna
estructura un poco más compleja.
Podemos ver el código fuente del ejemplo segundo de Handlebars, que hace uso del anterior
helper.
!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Beer List</title>
<script src="handlebars.js"></script>
<script src="jquery-2.0.0.min.js"></script>
{{/each}}
</script>
</head>
<body>
<strong>Our Beers...</strong><br/>
</div>
<script type="text/javascript">
(function() {
});
})();
$(function() {
http://desarrolloweb.com/manuales/manual-handlebars.html Página 15 de 25
Manual de Handlebars
url: '/api/Beers'
});
xhr.done(function (data) {
ctx.Beers = data;
$("#content").append(html);
$("#content").show();
});
});
</script>
</body>
</html>
Si te fijas en el código fuente del ejemplo del artículo anterior de este manual, encontrarás que
el Javascript que usamos para compilar la plantilla, invocar al backend para traernos por
AJAX el JSON y ejecutar la plantilla, es muy parecido. Realmente esto es normal, porque todo
ese proceso no variará apenas en los distintos ejemplos que hagamos. Lo que encontrarás que
varían son las plantillas y los helpers que podamos construir.
Recuerda que el JSON es el mismo en todos los ejercicios que hemos realizado sobre
Handlebars y que lo puedes ver en:
www.desarrolloweb.com/articulos/ejemplos/handlebars/Beers.json
{{# if Favorite}}
{{/if}}
{{/each}}
Con esto conseguimos que solo se impriman aquellas cervezas que se han maracado como
"Favorite".
http://desarrolloweb.com/manuales/manual-handlebars.html Página 16 de 25
Manual de Handlebars
if (value) {
} else
return "";
});
En este Helper se usa el parámetro "value" para cargar datos que será un boleano en el objeto
JSON. En caso positivo muestra una imagen de un icono y en caso negativo no muestra nada.
<br />
{{/each}}
Otra posibilidad interesante es que podríamos tener, por ejemplo, un helper que convirtiese un
nombre de usuario Twitter en un enlace a su perfil.
});
Fíjate que este helper tiene ya cierta complejidad, porque hacemos un tratamiento Javascript
al "value", para quitarle la "@" de un usuario Twitter. Para transformar un dato usamos el
método de String "substr()", con lo que demostramos que cuando se está programando un
helper no solamente se pueden mostrar datos de nuestro jSON tal cual, sino también se
pueden transformar antes de presentar en la página.
<ul>
</li>
{{/each}}
</ul>
http://desarrolloweb.com/manuales/manual-handlebars.html Página 17 de 25
Manual de Handlebars
http://desarrolloweb.com/manuales/manual-handlebars.html Página 18 de 25
Manual de Handlebars
Los helpers de bloque en Handlebars nos permiten cambiar el contexto. En los ejemplos vistos
hasta ahora en el Manual de Handlebars hemos trabajando siempre dentro del mismo
contexto, pero también podemos restringirlo a un sub-bloque en un contexto diferente.
Los contextos los podemos entender como niveles de profundidad en el archivo JSON.
Nosotros, en las plantillas, nos podemos meter en un nivel más profundo para acceder a las
propiedades disponibles en ese contexto.
<ul>
</li>
{{/each}}
</ul>
En ese código usamos siempre el mismo contexto. Para llamar al helper Twitter indicamos el
dato "LastCheckin.Drinker" para movernos entre niveles del JSON.
Ahora veamos este otro código, que haría lo mismo exactamente, pero efectuando un cambio
de contexto.
http://desarrolloweb.com/manuales/manual-handlebars.html Página 19 de 25
Manual de Handlebars
<ul>
{{#with LastCheckin}}
{{/with}}
</li>
{{/each}}
</ul>
Esto se consigue en helper que nos implemente un "contexto de bloque" y lo creamos mediante
la implementación de un código como este:
return options.fn(context);
});
Usamos también "registerHelper" con el nombre de este helper. Todo absolutamente normal,
pero tiene la diferencia que la función del helper recibe dos parámetros, el contexto y unas
opciones. El contexto es el objeto general y "options" es el subtemplate. Es un objeto propio de
Handlebars que te expone una función "fn" que te permite renderizar ese subtemplate en el
contexto que necesites.
Podemos ver otro template de bloque a continuación que generamos usando un helper
llamado "list". Este helper, cuyo código encontraremos un poquito más abajo, ya produce la
estructura de lista HTML UL y realiza la iteración entre todos los elementos del JSON.
{{#list Beers}}
{{#with LastCheckin}}
{{/with}}
{{/list}}
Para dar soporte a este template en el que usamos el helper "list", tenemos que crear la propia
función del helper. Se trata de otro de los denominados "helpers de bloque", que realiza una
lista y que hemos creado a propósito para el ejercicio.
http://desarrolloweb.com/manuales/manual-handlebars.html Página 20 de 25
Manual de Handlebars
});
En el código, vemos que se genera la lista UL usando otro contexto. Es una especie de bucle
"each" de Handlebars, pero creado por nosotros mismos en un helper de bloque que te
muestra el contenido en una lista.
Nota: como puedes haber imaginado, las estructuras que ya vienen de serie en Handlebars
como "each" o "if", internamente están desarrolladas por medio de helpers, solo que esos
helpers ya los tienes programados en la librería.
Con esto finalizan los ejemplos sobre Handlebars, la librería Javascript para crear plantillas en
Javascript. Si lo deseas, puedes descargar un zip con los ejemplos revisados en estos artículos.
http://desarrolloweb.com/manuales/manual-handlebars.html Página 21 de 25
Manual de Handlebars
Generar salida en HTML no es que sea lo más normal en las aplicaciones NodeJS, pero
siempre hay momentos en los que necesitas producir un pedazo de código en formato HTML y
para lo cual es suele ser mucho mejor trabajar mediante un sistema de templates.
Los motivos por los que usar un sistema de plantillas son varios. Lo fundamental es separar el
código por responsabilidades, lo que derivará en la producción de un código más mantenible.
También es recomendable porque te resultará mucho más fácil escribir el código de la salida de
tus aplicaciones. Además, Handlebars no sirve exclusivamente para producir código HTML,
por lo que te valdrá para cualquier otra salida de texto en general.
Existen diversos motores de plantillas que podrías usar en Node, pero me gusta Handlebars
por su sencillez. No tienes necesidad de usar otro lenguaje, como ocurre con Jade, y eso lo veo
una ventaja, sobre todo cuando quieres hacer un código limpio y de calidad, pero no quieres
invertir tiempo en aprender nada nuevo.
Instalar Handlebars
Como cualquier otra librería Node, comenzaremos instalando Handlebars mediante el
correspondiente comando de npm.
Una vez instalado en el proyecto, podremos hacer el require para traernos la funcionalidad de
la librería.
http://desarrolloweb.com/manuales/manual-handlebars.html Página 22 de 25
Manual de Handlebars
dato2: 'valor2'
});
Ahora en la variable "salida" tendrás la cadena resultante de producir ese template con el juego
de datos que se le ha enviado por parámetro.
Con lo que has aprendido ya puedes producir tus cadenas con cualquier contenido definido en
una plantilla almacenada en un fichero externo. Por lo que respecta a la sintaxis y posiblidades
de Handlebars ya te recomiendo nuestro Manual de Handlebars o la propia documentación
oficial.
Básicamente se trata de crear un módulo que tiene una única función que sirve para obtener
un template y compilarlo. Este módulo es el único de mi aplicación que conoce a Handlebars y
http://desarrolloweb.com/manuales/manual-handlebars.html Página 23 de 25
Manual de Handlebars
'use strict'
//sistema de archivos
let fs = require('fs');
//handlebars
module.exports = {
getTemplate
function getTemplate(archivo) {
return template;
Como ves, lo único que exporta hacia afuera es el método getTemplate, que recibe el archivo
que debe compilar para producir la correspondiente plantilla.
Con este módulo generado, usarlo para producir plantillas en cualquier parte de mi proyecto es
tan sencillo como esto:
Quitando el require, que lo debes hacer una única vez, la generación de la plantilla se reduce a
una línea de código. No es que fuera muy compleja, esa compilación, pero había que ir al
sistema de archivos a traerse el código del template, compilarlo, etc. Ahora queda mucho más
conciso y la complejidad encapsulada en un sencillo módulo.
Conclusión
Aprender Handlebars no te llevará más de 10 minutos y usarlo para generar plantillas, con las
que producir salida cómodamente y en cualquier formato, te ahorrará mucho tiempo de
desarrollo, evitando código difícil de mantener, a medio y largo plazo.
Con este artículo ahora lo tienes mucho más fácil de integrar en NodeJS, por lo que no hay
excusas para comenzar a trabajar con este sencillo pero potente sistema de templates.
http://desarrolloweb.com/manuales/manual-handlebars.html Página 24 de 25
Manual de Handlebars
http://desarrolloweb.com/manuales/manual-handlebars.html Página 25 de 25