node handlebars example javascript node.js handlebars.js express

javascript - handlebars node js example



Node.js con Handlebars.js en el servidor y el cliente (7)

Debe usar plantillas de cliente compiladas previamente. Se ejecutan más rápido y le permiten usar el mismo lenguaje de plantilla en el servidor y el cliente.

  1. Instalar manillares globalmente npm install handlebars -g
  2. Precompila tus plantillas manillas handlebars client-template1.handlebars -f templates.js
  3. Incluye templates.js <script src="templates.js"></script>
  4. Ejecute la plantilla var html = Handlebars.templates["client-template1"](context);

https://stackoverflow.com/a/13884587/8360

Tengo una aplicación en Node.js que usa Expressjs y Handlebars como motor de plantilla.

Expressjs usa diseños y luego representa vistas. El diseño (layout.hbs) se ve así:

<!doctype html> <html lang="en"> <head> </head> <body> {{{body}}} </body> </html>

El {{{body}}} se reemplaza del lado del servidor, dentro de node.js cuando accede a una ruta. Por ejemplo:

app.get(''/'', function(req, res){ res.render(''index''}) })

Reemplazará la etiqueta {{{body}}} con los contenidos de index.hbs.

Ahora, en el lado del cliente estoy usando Backbone.js y quiero usar Handlebars para las vistas controladas a través de Backbone. El problema es que debido a que estas páginas ya se procesaron a través de los manubrios, cuando intento usar manubrios dentro de él (o manubrios dentro de manubrios) no funciona. No hay errores, simplemente no reemplaza las etiquetas con datos.

¿Alguien ha encontrado esto antes o tiene alguna idea de trabajo?

¡Gracias!


He solucionado esto pasando plantillas de cliente a través de plantillas de servidor.

Entonces, en el lado del servidor, lea todas las plantillas del lado del cliente en una matriz y páselo a su función de renderizado en el lado del servidor.

En su controlador de ruta, haga algo como:

readTemplates(function(err, clientTemplates) { res.render("page", { clientTemplates: clientTemplates; }); });

Y luego en layout.hbs:

{{#each clientTemplates}} <script type="text/handlebars id="{{this.filename}}" > {{{this.template}}} </script> {{/each}}

Aquí estoy usando nombres de archivos sin extensiones como id de la plantilla para que puedan ser referenciados desde vistas de Backbone. Ah, y recuerda implementar el almacenamiento en caché para el modo de producción.

Sí, esto apesta.

Creo que deberíamos escribir un ayudante de Handlebars / Express / Connect para esto.


No me gustó la solución de precompilación (porque quiero definir plantillas en el mismo archivo donde las usaré) ni la ingenua /{{ solución de escape (porque necesita el compilador completo de Handlebars y más código de JavaScript) así que surgió con una solución híbrida que utiliza los ayudantes de Handlebars:

1) Registre un nuevo ayudante llamado "plantilla" en la configuración del servidor

var hbs = require(''hbs''); hbs.registerHelper("template", function(key, options){ var source = options.fn().replace("//{{", "{{"); var ret = ''<script>/n'' + key + '' = function(opt){/n'' + ''return Handlebars.template('' + hbs.handlebars.precompile(source) + '')(opt);/n'' + ''}/n'' + ''</script>''; return ret; });


2) Úselo en cualquier lugar de su página web del lado del cliente (con /{{ escape para los parámetros del lado del cliente)

{{#template "myTemplate"}} <div> <p>Hello /{{this.name}}!</p> </div> {{/template}}

(el servidor lo precompilará en algo como esto)

<script> myTemplate = function(opt){ return Handlebars.template(/* HBS PRECOMPILATED FUNCTION */)(opt); } </script>


3) Simplemente llame a la función donde lo necesite en javascript del lado del cliente

var generatedHtml = myTemplate("world"); // = <div><p>Hello world!</p></div> $("#myDiv").html(generatedHtml); // or whatever


Sí, es un problema pegajoso, algo así como los problemas de citas en los scripts de shell que se convierten en un nido de citas entre comillas.

Mi solución es usar jade (a la haml) en expressjs (lado del servidor) para generar plantillas basadas en barras de control para el cliente. De esta forma, el servidor usa una sintaxis (jade) y el cliente usa otra (barras de control). Estoy en la misma encrucijada que tú, así que tengo el mismo desafío.

Por supuesto, el jade no es esencial (aunque está listo para expressjs). Puede elegir cualquier motor de plantilla (que no sea de manubrio) para el servidor, y / o puede usar barras de control en el servidor con plantillas que no sean del manubrio en el cliente, siempre que las dos sintaxis de sus motores de plantillas elegidos no chocar. Como estoy usando emberjs en el cliente y usa la sintaxis del manillar (de manera predeterminada), prefiero usar la sintaxis de emberjs + handlebars en el cliente. Así que expressjs + jade se convirtió en un ajuste natural para el servidor.


Tienes 2 opciones. El segundo es LA mejor manera de hacerlo:

1) Escape de los bigotes

<script type="text/x-handlebars" data-hbs="example"> <p>/{{name}}</p> </script>

2) Precompilación

Esto compilará la plantilla en el servidor antes de que vaya al cliente. Esto hará que la plantilla esté lista para usar y reduce la carga en el navegador.


Una manera fácil de hacerlo es simplemente agregar un / antes del {{ en un archivo de barras de herramientas. Por ejemplo:

<script type="text/x-template" id="todo-item-template"> <div class="todo-view"> <input type="checkbox" class="todo-checkbox" /{{checked}}> <span class="todo-content" tabindex="0">/{{text}}</span> </div> <div class="todo-edit"> <input type="text" class="todo-input" value="/{{text}}"> </div> <a href="#" class="todo-remove" title="Remove this task"> <span class="todo-remove-icon"></span> </a>

El código anterior se representará en el cliente con las etiquetas {{..}} conservadas.


¡Auto promoción sin vergüenza!

Quería hacer lo mismo de compartir cliente / servidor, así que escribí un pequeño paquete npm para ayudar:

node-handlebars-precompiler

Lo preparé en un par de horas según el compilador de la línea de comandos en el repositorio de manubrios de wycats. No es el mejor código del mundo, pero me ha hecho bien el trabajo.

EDITAR: Ya no estoy manteniendo este paquete. Si desea hacerse cargo, póngase en contacto conmigo a través de Github. Principalmente uso plantillas de Jade ahora, así que no tiene sentido que continúe como mantenedor.