2012-07-03 17 views
34

Estoy escribiendo un CMS en Node.js con Express Framework. En mi CMS Tengo varios módulos para los usuarios, páginas, etc.Rutas de vista múltiple en Node.js + Express

quiero que cada módulo tendrá sus archivos en carpetas separadas , incluyendo los archivos de vista. ¿Alguien sabe cómo puedo lograr eso?

Estoy usando swg como motor de plantilla, pero puedo reemplazarlo por otra cosa si eso ayuda.

+1

¿Algo como esto funcionaría para usted? http://stackoverflow.com/questions/9470466/node-express-js-overriding-where-to-look-for-the-views-folder-for-each-reque –

+0

http://stackoverflow.com/questions/ 36374424/mean-app-with-admin-panel-and-client-panel? Answertab = active # tab-top –

Respuesta

35

Última actualización

La vista característica de varios carpetas se apoya en el marco expreso desde 4,10

Sólo tiene que pasar una serie de ubicaciones a la propiedad views, como tal.

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

Express 2.0

Por lo que yo sé expresar no soporta múltiples rutas de ver o espacios de nombres en el momento (como el middleware estática hacer)

pero puede modificar la búsqueda lógica usted mismo para que funcione de la manera que desee, por ejemplo:

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

Habilitará la nueva lógica mediante callin g la función anterior y pasando expresan como un parámetro, y entonces usted será capaz de especificar una matriz de puntos de vista a la configuración:

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

O, si lo prefiere, puede parchear el marco directamente (actualización la view.js archivo dentro de ella)

Esto debería trabajo in exprés 2.x, no estoy seguro si lo hará con la nueva versión (3.x)

ACTUALIZACIÓN

Desgraciadamente la solución anterior no funcionará in exprés 3.x desde express.view sería indefinido

Otra posible solución será la de proxy de la respuesta .render función y ajustar la configuración de la carpeta puntos de vista hasta que obtiene un partido:

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

yo no lo he probado, se siente poco limpia a mí de todos modos, desgraciadamente, esta característica ha sido empujado de nuevo: https://github.com/visionmedia/express/pull/1186

ACTUALIZACIÓN 2

Esta característica se ha agregado in exprés 4.10, ya que la solicitud de extracción siguiente se ha fusionado: https://github.com/strongloop/express/pull/2320

+0

No se habla de implementar esto en 3.x, por lo que su función debería funcionar en la nueva versión. – Pickels

+0

Sí, parece que sí, pero algunas (¿muchas?) API en 3.x cambiaron, y creo que se refactorizaron, parece que últimamente no cambiaron demasiado el archivo view.js: https://github.com/ visionmedia/express/commits/master/lib/view.js Probablemente funcione, lo probaré cuando tenga algo de tiempo libre – BFil

+0

He convertido esto en un módulo que funciona para Express 4.x. https://www.npmjs.org/package/multi-views –

5

Aquí hay una solución para Express 3.x. Los parches de mono expresan el objeto "Ver" de 3.x para hacer el mismo truco de búsqueda que la solución de @SombraCloud anterior. Desafortunadamente, la búsqueda de ruta para el objeto View es menos limpia, ya que 3.x no la expone a express, por lo que debe excavar en las entrañas de node_modules.

function enable_multiple_view_folders() { 
    // Monkey-patch express to accept multiple paths for looking up views. 
    // this path may change depending on your setup. 
    var View = require("./node_modules/express/lib/view"), 
     lookup_proxy = View.prototype.lookup; 

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

enable_multiple_view_folders(); 
11

Además de la respuesta @ user85461, la parte de requerir vista no funcionó para mí. lo que hice: se ha eliminado la materia camino y se trasladó todo a un módulo que podría requerir, patch.ViewEnableMultiFolders.js (Funciona con expreso actual):

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; 

y utilizado:

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

Sin embargo, puede poner todos los archivos de vista dentro de la carpeta 'ver', pero separar la vista de cada módulo en sus propias carpetas dentro de la carpeta 'ver'. Por lo tanto, la estructura es algo como esto:

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

Establecer los archivos de vista como de costumbre:

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

Y cuando rinde por cada módulo, incluir el nombre del módulo:

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

o incluso el nombre del submódulo:

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

Esta solución también funciona en express antes de la versión 4.x,

Cuestiones relacionadas