This is my views folder structure:
- views
- layouts
layout.hbs
- partials
part.hbs
home.hbs
I'm rendering the template width:
app.use(views(__dirname + '/views', {
extension: 'hbs',
map: { hbs: 'handlebars' }
}));
router.get('/', async (ctx) => {
await ctx.render('home', {
Name: 'Iris',
Type: 'Web',
Path: '/'
});
});
What I want is to define the main layout file and the partials folder, just like if it was in express-handlebars
. Really there's no way to achieve this with koa-views
and pure handlebars
?
I have to use koa-hbs
or koa-handlebars
? But they using soon deprecated features (and Handlebars v2.0.0, v3.0.0):
koa deprecated Support for generators will been removed in v3.
See the documentation for examples of how to convert old middleware
https://github.com/koajs/koa/tree/v2.x#old-signature-middleware-v1x app.js:45:5
EDIT:
Seems like koa-hbs
and koa-handlebars
plugins not compatible with koa v2
. So there's no way to use koa v2
, partials
and layouts
rendered with handlebars
at the moment? :( Without those (define layouts
, partials
) handlebars
are useless. So still stucked with express
...
koa-hbs is really just using handlebars .registerPartial
under the hood.
As basic as possible:
var handlebars = require('handlebars'),
fs = require('fs')
handlebars.registerPartial(
'defaultLayout',
fs.readFileSync(__dirname + '/views/layouts/default.html', 'utf8')
)
// then continue with loading the application...
But you probably want the convenience of it just loading your entire partials folder on startup though.
handlebars.registerPartial
. It should resolve the Promise when they are all registered.Here's an example that I use:
var fs = require('fs'),
handlebars = require('handlebars'),
glob = require('glob'), // for convenience, npm install glob
path = require('path')
function readAsPromise (path) {
return new Promise(function (resolve, reject) {
fs.readFile(path, 'utf8', function (err, data) {
resolve({path: path, data: data})
})
})
}
function registerPartial (partial) {
var partialName = path.basename(partial.path, '.hbs')
handlebars.registerPartial(partialName, partial.data)
}
var loadPartials = new Promise(function (resolve, reject) {
glob('./views/partials/*.hbs', function (err, files) {
Promise.all(files.map(readAsPromise)).then(function (partials) {
partials.forEach(registerPartial)
resolve()
})
})
})
Now the question is which version of Koa are you using
// koa 1
app.use(function* (next) {
yield loadPartials
yield next
})
// latest koa
app.use(async (ctx, next) => {
await loadPartials
})
Now just use partials in handlebars as normal. This works fine with koa-views which will require the same instance of handlebars