2012-07-03 8 views
34

Ich schreibe ein CMS auf Node.js mit Express Framework. Auf meinem CMS habe ich mehrere Module für Benutzer, Seiten, usw.Mehrere Ansichtspfade auf Node.js + Express

Ich möchte, dass jedes Modul seine Dateien auf separaten Ordner, einschließlich der View-Dateien haben. Wer weiß, wie kann ich das erreichen?

Ich benutze swig als meine Vorlage-Engine, aber ich kann es zu etwas anderem ersetzen, wenn es hilft.

+1

Würde so etwas für Sie funktionieren? http://stackoverflow.com/questions/9470466/node-express-js-overriding-where-to-look-for-the-view-folder-for-each-reque –

+0

http://stackoverflow.com/questions/ 36374424/mean-app-mit-admin-panel-und-client-panel? Answertab = aktiv # tab-top –

Antwort

35

Last Update

Die Mehrfachansicht Ordner verfügen durch den Rahmen seit Express 4.10 unterstützt wird

einfach eine Reihe von Orten an der views Eigenschaft übergeben, wie so.

app.set('views', [__dirname + '/viewsFolder1', __dirname + '/viewsFolder2']); 

Express 2.0

Soweit ich auszudrücken weiß nicht, mehrere Ansichts Pfade oder Namensräume im Moment (wie die statische Middleware tun)

unterstützen Aber Sie können die Lookup ändern Logik selbst, so dass es, wie Sie wollen, zum Beispiel funktioniert:

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) 
    }; 
} 

Sie die neue Logik von callin ermöglichen g die Funktion oben und vorbei auszudrücken als Parameter, und dann werden Sie eine Reihe von Ansichten der Konfiguration angeben können:

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

Oder, wenn Sie möchten, können Sie den Rahmen Patch direkt (Aktualisierung die view.js Datei in it)

Dies sollte Arbeit in Express 2.x, nicht sicher, ob es mit der neuen Version (3.x)

UPDATE

Unluckily die obige Lösung nicht da express.view in Express 3.x arbeitenundefined

Eine andere mögliche Lösung für Proxy wird die Antwort sein würde. Funktion machen und den Ansichten Ordner Config gesetzt, bis es eine Übereinstimmung bekommt:

var renderProxy = express.response.render; 
express.render = function(){ 
    app.set('views', 'path/to/custom/views'); 
    try { 
     return renderProxy.apply(this, arguments); 
    } 
    catch (e) {} 
    app.set('views', 'path/to/default/views');  
    return renderProxy.apply(this, arguments); 
}; 

ich es nicht getestet habe, ist es mir sehr hacky fühlt sich trotzdem, unglücklicherweise diese Funktion wieder zurück geschoben wurde: https://github.com/visionmedia/express/pull/1186

UPDATE 2

Diese Funktion in Express 4.10 hinzugefügt wurde, da der folgende Pull-Request zusammengefasst wurde: https://github.com/strongloop/express/pull/2320

+0

Es gibt keine Diskussion über die Implementierung in 3.x, so dass Ihre Funktion in der neuen Version funktionieren sollte. – Pickels

+0

Ja es scheint so, aber einige (viele?) APIs in 3.x geändert, und ich denke, es wurde überarbeitet, es scheint nicht, dass sie die view.js-Datei in letzter Zeit zu viel geändert: https://github.com/ visionmedia/express/commits/master/lib/view.js Es wird wahrscheinlich funktionieren, ich werde es testen, wenn ich etwas freie Zeit habe – BFil

+0

Ich habe dies zu einem Modul gemacht, das für Express 4.x funktioniert. https://www.npmjs.org/package/multi-views –

5

Hier ist eine Lösung für Express 3.x. Es Affen-Patches drücken 3.x "View" -Objekt, um den gleichen Lookup-Trick als @ ShadowCloud-Lösung oben zu tun. Leider ist die Pfadsuche für das Objekt View weniger sauber, da 3.x es nicht express aussetzt - Sie müssen also in die Eingeweide von node_modules graben.

11

Zusätzlich zu @ user85461 Antwort, die Anforderung Ansicht Teil hat nicht für mich arbeiten. Was ich tat: entfernt das Zeug Weg und das alles zu einem Modul bewegt i, erfordern könnte patch.ViewEnableMultiFolders.js (Arbeitet mit aktuellem express):

function ViewEnableMultiFolders(app) { 
    // Monkey-patch express to accept multiple paths for looking up views. 
    // this path may change depending on your setup. 
    var lookup_proxy = app.get('view').prototype.lookup; 

    app.get('view').prototype.lookup = function(viewName) { 
     var context, match; 
     if (this.root instanceof Array) { 
      for (var i = 0; i < this.root.length; i++) { 
       context = {root: this.root[i]}; 
       match = lookup_proxy.call(context, viewName); 
       if (match) { 
        return match; 
       } 
      } 
      return null; 
     } 
     return lookup_proxy.call(this, viewName); 
    }; 
} 

module.exports.ViewEnableMultiFolders = ViewEnableMultiFolders; 

und gebraucht:

var Patch = require('patch.ViewEnableMultiFolders.js'); 
Patch.ViewEnableMultiFolders(app); 
app.set('views', ['./htdocs/views', '/htdocs/tpls']); 
4

Sie können jedoch alle Ansichtsdateien in den Ordner "view" einfügen, aber die Ansicht jedes Moduls in seine eigenen Ordner im Ordner "view" aufteilen. So ist die Struktur etwas wie folgt aus:

views 
--moduleA  
--moduleB 
----submoduleB1 
----submoduleB2 
--moduleC 

Stellen Sie die Ansicht Dateien wie gewohnt:

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

Und wenn für jedes Modul machen, umfassen den Namen des Moduls:

res.render('moduleA/index', ...); 

oder sogar Submodulname:

res.render('moduleB/submoduleB1/index', ...); 

Diese Lösung funktioniert auch in Express vor Version 4.x,

Verwandte Themen