Ändern Sie den Express-Ansichtsordner basierend darauf, wo sich die Datei befindet, die res.render () aufgerufen wird

77

Ich möchte den Ansichtsordner von Express ändern, wenn ich res.render () aufrufe.

Wenn ich beispielsweise res.render (viewName) in /folder/file.js aufrufe, möchte ich, dass Express nach der Ansicht in / folder / views sucht.

Wenn sich die Datei in /folder1/folder2/file.js befindet, möchte ich, dass Express nach der Ansicht in / folder1 / folder2 / views sucht

Ist es möglich ?

Talysson
quelle

Antworten:

122

Mit dieser Methode können Sie set()die Standardeinstellungen von Express neu definieren.

app.set('views', path.join(__dirname, '/yourViewDirectory'));

Für eine dynamische Pfadänderung können Sie Folgendes tun:

var express = require('express');
var path = require('path');
var app = express();

app.engine('jade', require('jade').__express);
app.set('view engine','jade');

app.customRender = function (root,name,fn) {

    var engines = app.engines;
    var cache = app.cache;

    view = cache[root+'-'+name];

    if (!view) {
        view = new (app.get('view'))(name, {
          defaultEngine: app.get('view engine'),
          root: root,
          engines: engines
        });

        if (!view.path) {
          var err = new Error('Failed to lookup view "' + name + '" in views directory "' + root + '"');
          err.view = view;
          return fn(err);
        }

        cache[root+'-'+name] = view;
    }

    try {
      view.render(opts, fn);
    } catch (err) {
      fn(err);
    }
}

app.get('/', function(req, res) {

    app.customRender(path.join(__dirname, '/path/to/user/'),'index',function (err,html) {
        if (err)
            res.send(404);
        else
            res.send(200,html);
    });

});

app.listen(3000);
Pedro Nasser
quelle
4
Es sieht gut aus, aber wie kann ich es dynamisch machen? Wenn zwei Benutzer gleichzeitig auf unterschiedliche Pfade zugreifen, überschreibt einer der app.set den anderen, nicht wahr?
Talysson
Können Sie mich auf die Dokumentation zu app.get ('view') verweisen? Ich kann es nicht finden. Ich sehe 'view' in der Liste hier nicht: expressjs.com/en/api.html#app.settings.table . Ich mag die Idee, undokumentierte Funktionen zu verwenden, nicht.
Nuzzolilo
54

Anstatt einfach Ihren Ansichtsnamen an die Renderfunktion zu übergeben, können Sie einen relativen oder absoluten Pfad übergeben.

Einfaches Beispiel:

app.get('/your/path', function(req, res) {
    //viewname can include or omit the filename extension
    res.render(__dirname + '/folder/with/views/viewname'); 
});​​​​​​​​​​
Nuzzolilo
quelle
5
Dies scheint einfacher zu sein, als die Rendering-Funktion zu überschreiben!
Stein
10

Das ist ziemlich einfach

Um den Ansichtsordner von Express zu ändern, wenn Sie res.render () aufrufen, legen Sie einfach den Pfad fest, in dem sich die Ansichten befinden.

app.set('views','./folder1/folder2/views');

Dies ändert den Pfad, in dem Express nach bestimmten Ansichten suchen würde.

Vickar
quelle
1
Dies ist am besten, weil es am einfachsten ist, keine zusätzlichen require. ...einfach.
Ronnie Royston
Richtig @MonarchWadia
Abdalla Arbab
Führt dies zu einer Race-Bedingung, wenn mehrere Anforderungen den Ansichtsordner zurücksetzen?
AjahnCharles
4

(Entschuldigung, ich kann noch keinen Kommentar abgeben)

@ nuzzolilos Antwort funktioniert gut. Aber wenn Sie ES6 bevorzugen

app.get('/path', function (req, res) {
    res.render(`${__dirname}/templates_dir/index`, { data: "value" });
});

Dies verbessert einfach die Lesbarkeit des Codes;)

Collin
quelle
3

Sie können den relativen Pfad auch ermitteln, indem Sie Folgendes verwenden require.resolve: res.render(require.resolve('./folder/with/views/viewname'));

Luke Chinworth
quelle