ericf / express-handlebars

A Handlebars view engine for Express which doesn't suck.
BSD 3-Clause "New" or "Revised" License
2.31k stars 382 forks source link

Multiple view directories. #138

Open Koded opened 9 years ago

Koded commented 9 years ago

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.

acazacu commented 7 years ago

Was this ever merged?

jswny commented 7 years ago

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.

the-t-in-rtf commented 7 years ago

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.

sidhuko commented 7 years ago

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 graceful-fs@1.2.3: 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.
the-t-in-rtf commented 7 years ago

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.

soyaine commented 6 years ago

So it is still not supported in express-handlebars 3.0.0 to use multiple view directories?

sidhuko commented 6 years ago

Not since I last checked in June this year - if you come up with a solution I would be interested to see!

soyaine commented 6 years ago

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.

morgannewman commented 5 years ago

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.