Node.js and express: use more than one view directory

Using node.js 0.12.35 and Express 4.x. I currently need to be able to access various locations for my views. therefore, the Documentation Express 4.x API says that the views property of the app.set method will accept "A directory or array of directories for the application views. If an array, the views are viewed in the order they occur in the array." So can you please give me an example on how to define such an array? Everything I've tried so far has ended up in this error message. I used the following style for my application.

app.set('views', ['/my/path/components/views/' + 'base', '/my/path/components/views/' + 'starters']);

      

but that won't work. I am getting the error:

TypeError: **Arguments to path.join must be strings**
    at path.js:360:15

      

So what am I missing? How do I add an array to app.set? Actually I tried to debug it myself and looked at the view.js script expressions. From there I can see that the array is correctly passed to this script, I can see two different root paths, but from there it does not correctly build the full path to the various, in my case .jade files, since I am using the jade engine. This means that the following path.join with the root path and the file itself does not work and throws an error. Digging deeper, it looks like the .join path cannot accept arrays? But how should the multiple view path work? I thought Express 4.x should be able to use multiple views, but how if the view.js that comes out of the box isn't capable of handling arrays like this? I am lost...

+3


source to share


3 answers


So in the end, and with robertklep's help, the answer is that it was a version issue in package.json. It doesn't work with these dependencies

"dependencies": {
"express": "~4.9.0",
"body-parser": "~1.8.1",
"cookie-parser": "~1.3.3",
"morgan": "~1.3.0",
"serve-favicon": "~2.1.3",
"debug": "~2.0.0",
"jade": "~1.6.0"

      

}



But it works well with declared dependencies:

 "dependencies": {
    "express": "~4.12.4",
    "body-parser": "~1.12.4",
    "cookie-parser": "~1.3.5",
    "morgan": "~1.5.3",
    "serve-favicon": "~2.2.1",
    "debug": "~2.2.0",
    "jade": "~1.10.0"
  }

      

0


source


You cannot set multiple viewing folders. However, you can set views:

app.set('views', '/my/path/components/views/');

      

and then for rendering like index.html from base folder use



res.render('base/index');

      

Even if the array you were using you would need to say which folder you want to see, right? How would you do it if I may ask?

0


source


The function of using more than one browse folder is supported natively in Express> = 4.10

You must pass an array of locations to the views property, for example:

app.set('views', [__dirname + '/oneViewFolder', __dirname + '/anotherViewFolder']);

      

In an early version of Express, you have to change the search logic yourself so that it works the way you want it, for example:

function enableMultipleViewFolders(express) {
// proxy function to the default view lookup
var lookupProxy = express.view.lookup;

express.view.lookup = function (view, options) {
    if (options.root instanceof Array) {
        // clones the options object
        var opts = {};
        for (var key in options) opts[key] = options[key];

        // loops through the paths and tries to match the view
        var matchedView = null,
            roots = opts.root;
        for (var i=0; i<roots.length; i++) {
            opts.root = roots[i];
            matchedView = lookupProxy.call(this, view, opts);
            if (matchedView.exists) break;
        }
        return matchedView;
    }

    return lookupProxy.call(express.view, view, options)
};

      

}

You can enable the new logic by calling the function above and passing the expression as a parameter, and then you can specify an array of views to configure, like in the previous example:

var express = require('express');
enableMultipleViewFolders(express);
app.set('views', [__dirname + '/oneViewsFolder', __dirname + '/anotherViewFolder']);

      

I hope this helped you

0


source







All Articles