2011-11-09 15 views
21

Estoy usando el handlebars.js hbs wrapper en express.js. Tengo plantillas que funcionan bien, pero necesito agregar parciales para representar con mis vistas.Módulo Express.js hbs - registrar parciales del archivo .hbs

me gustaría hacer algo como esto:

hbs.registerPartial('headPartial', 'header'); 
// where "header" is an .hbs file in my views folder 

Sin embargo, se está lanzando una "cabecera parcial no se puede encontrar".

Puedo hacer que registerPartial funcione si paso una cadena de html al segundo parámetro, pero me gustaría usar archivos de vista separados para mis parciales.

No he encontrado ninguna documentación sobre esto, pero espero que me pueda estar perdiendo algo fácil.

¿Alguien sabe cómo usar view files en el método registerPartial? Si es así, ¿cómo implemento esto?

ACTUALIZACIÓN

Para dar más contexto, permítanme añadir más código. Aquí está mi archivo de "servidor" - app.js

var express = require('express') 
, routes = require('./routes') 
, hbs = require('hbs'); 

var app = module.exports = express.createServer(); 

// Configuration 

app.configure(function(){ 
    app.set('views', __dirname + '/views'); 
    app.set('view engine', 'hbs'); 
    app.use(express.bodyParser()); 
    app.use(express.methodOverride()); 
    app.use(app.router); 
    app.use(express.static(__dirname + '/public')); 
}); 

app.configure('development', function(){ 
    app.use(express.errorHandler({ dumpExceptions: true, showStack: true })); 
}); 

app.configure('production', function(){ 
    app.use(express.errorHandler()); 
}); 

// this is the line that generates the error 
hbs.registerPartial('headPartial', 'header'); 

// What I'm expecting is for "headPartial" to be a compiled template partial 
// of the template within views/header.hbs, but it is not loading this way. 
// If I do something like hbs.registerPartial('headPartial', '<p>test</p>'); 
// then it does work. I need to know how to pass an .hbs file to the 
// registerPartial method. 

// Routes 
app.get('/', routes.index); 

app.listen(3000); 

Y aquí es mi archivo routes.index:

exports.index = function(req, res){ 
    res.render('index', { title: 'Express' }) 
}; 

En mi carpeta de puntos de vista, tengo tres plantillas:

views/ 
    header.hbs (this is my partial) 
    index.hbs 
    layout.hbs 

En mi archivo index.hbs, llamo al parcial 'headPartial' con:

{{> headPartial}} 

Cualquier ayuda es muy apreciada.

Respuesta

36

Este code cargas todas las plantillas parciales de un directorio y los pone a disposición de nombre de archivo:

var hbs = require('hbs'); 
var fs = require('fs'); 

var partialsDir = __dirname + '/../views/partials'; 

var filenames = fs.readdirSync(partialsDir); 

filenames.forEach(function (filename) { 
    var matches = /^([^.]+).hbs$/.exec(filename); 
    if (!matches) { 
    return; 
    } 
    var name = matches[1]; 
    var template = fs.readFileSync(partialsDir + '/' + filename, 'utf8'); 
    hbs.registerPartial(name, template); 
}); 
+1

Niza. ¡Una forma rápida de tener todos los parciales disponibles cuando sea necesario! – swatkins

+0

Gracias Ben, esto realmente ayudó mucho. – Dave

11

Parece que la creación de una variable y tirando en el código de la plantilla manualmente funciona:

var hbs = require('hbs') 
    , fs = require('fs') 
    , headerTemplate = fs.readFileSync(__dirname + '/views/_header.hbs', 'utf8'); 

y posterior:

hbs.registerPartial('headPartial', headerTemplate); 
+0

Gracias por esto, funciona muy bien – iancrowther

+0

esto parece mucho trabajo extra para demandar parciales en Express3 – chovy

35

Para mayor comodidad, registerPart IALS proporciona una forma rápida de cargar todos los parciales de un directorio específico:

var hbs = require('hbs'); 
hbs.registerPartials(__dirname + '/views/partials'); 

Parciales que se cargan desde un directorio se nombran en base a su nombre, donde los espacios y guiones se reemplazan con un carácter de subrayado:

template.html  -> {{> template}} 
template 2.html -> {{> template_2}} 
login view.hbs  -> {{> login_view}} 
template-file.html -> {{> template_file}} 

¡Salud!

+0

Hola, ¿funcionará para subdirectorios también? En este caso, ¿cómo podemos obtener las vistas? Gracias –

+0

Esto es genial, pero tenga en cuenta que carga parciales de forma asíncrona con una devolución de llamada: probablemente no desee aceptar solicitudes hasta que esto finalice: [Ayudantes y parciales] (https://github.com/pillarjs/hbs # helpers-and-partials) –

1

Para mí tenía el archivo de plantilla my-partial.HBS

Entonces trató de acceder a ellos a través de:

{{> my-partial }} 

embargo, el parcial se almacena en HBS como my_partial independientemente del nombre de archivo.

Esto es gracias a la versión 3.1.0 HBS línea 218

.slice(0, -(ext.length)).replace(/[ -]/g, '_').replace('\\', '/'); 

Esto es en el readme

0

Para mí, tengo una función como:

var hbs = require('hbs'); 
var fs = require('fs');  
var statupfunc = { 
     registerHbsPartials : function(){ 
     //this is run when app start 
     hbs.registerPartials(__dirname + "/" + resource.src.views + '/partials');   
     }, 
     registerOneHbsPartials : function(event){ 
     //this is run for gulp watch 
     if(event.type == 'deleted') 
     { 
      return; 
     } 
     var filename = event.path; 
     var matches = /^.*\\(.+?)\.hbs$/.exec(filename); 
     if (!matches) { 
      return; 
     }  
     var name = matches[1];  
     var template = fs.readFileSync(filename, 'utf8');  
     hbs.registerPartial(name, template);  
     } 
    }; 

Run statupfunc .registerHbsPartials al inicio de la aplicación y luego registrar gulp watch con statupfunc.registerOneHbsPartials para registrar parciales de nueva creación

gulp.task('watch', function() { 
    gulp.watch(resource.src.views + '/partials/*.*', statupfunc.registerOneHbsPartials); 
}); 
Cuestiones relacionadas