express-handlebars
express-handlebars copied to clipboard
Multiple view directories.
Since version 2.0.0
you can no longer use multiple view directories:
With the following code:
server.set('view engine', '.hbs');
server.set('views', [
dirPath1,
dirPath2,
dirPath3
]);
I get:
TypeError: Arguments to path.resolve must be strings
This was ok in version 1.1.0
, and it appears as though this should be supported when looking at the Express documentation (http://expressjs.com/api.html).
From option views
:
A directory or an array of directories for the application's views. If an array, the views are looked up in the order they occur in the array.
Was this ever merged?
This should be looked at. According to the Express API, the views
option can be an array but this causes express-handlebars
to crash at the renderView
method.
~~An array of views worked with version 1.1.2, this behavior has definitely changed, I believe as of 2.0.0.~~
OK, duh, I see the same info in the description, sorry to have missed that.
Two years on I'm guessing this regression of behaviour hasn't been fixed anywhere. Anyone have a solution on this thread?
graceful-fs v3 will no longer work on node.js >= v7 so the option to use 1.1.0 will be broken when node v8 becomes LTS in October.
npm WARN deprecated [email protected]: graceful-fs v3.0.0 and before will fail on node releases >= v7.0.
Please update to graceful-fs@^4.0.0 as soon as possible. Use 'npm ls graceful-fs' to find it in the tree.
Since we were stuck at an older version of express-handlebars until this is resolved, express-handlebars ended up being our main source of vulnerabilities coming from inherited dependencies. I ended up writing my own lightweight view engine to replace express-handlebars, but it's very much unique to our "stack", and a bit much to expect anyone else to use. In our case, we already had a standalone handlebars renderer, wiring that into something that supported the view engine API was not all that hard.
So it is still not supported in express-handlebars 3.0.0 to use multiple view directories?
Not since I last checked in June this year - if you come up with a solution I would be interested to see!
When I try to set two folders in the app.set('views', ['views1', 'views2'])
, I get the error:
TypeError: Path must be a string. Received [ 'views1', 'views1' ]
at assertPath (path.js:7:11)
at Object.relative (path.js:1226:5)
But it works well either by app.set('views', 'views1')
or app.set('views', 'views2')
.
After read this issue, I'm puzzled whether have I understand it. But it seems still a lot people suffer from this such as this issue.
I'm trying to find a solution, but it doesn't look well.
Not a great long-term solution, but if all your handlebars views are in a single folder, here's a temporary solution.
const hbsViews = path.join(__dirname, '/views'); // path to your handlebars views
const hbsEngine = exphbs({
layoutsDir: path.join(__dirname, '/views/layouts'),
defaultLayout: 'main',
extname: '.hbs',
});
app.engine(
'.hbs',
function(filePath, options, callback) {
options.settings.views = hbsViews;
hbsEngine(filePath, options, callback);
}
);
This works because it fixes this line, which breaks when you set views to be an array.