Node.js + Express上的多个视图path

我正在使用Express FrameworkNode.js上编写一个CMS。 在我的CMS上,我有几个用户,页面等模块

我希望每个模块都将他的文件放在单独的文件夹中包括视图文件 。 任何人都知道我该怎么做到这一点?

我使用swig作为我的模板引擎,但是如果它能帮上 ,我可以把它replace成别的东西。

       

网上收集的解决方案 "Node.js + Express上的多个视图path"

最后更新

自Express 4.10以来,该框架支持多视图文件夹function

只需传递一个位置数组到views属性,像这样。

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

Express 2.0

据我所知,express现在不支持多个视图path或命名空间(就像静态中间件一样)

但是,您可以自己修改查找逻辑,以便按照您希望的方式工作,例如:

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

您将通过调用上述函数并将express传递为参数来启用新的逻辑,然后您将能够为configuration指定一个视图数组:

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

或者,如果你愿意,你可以直接修补框架(更新里面的view.js文件)

这应该工作在Express 2.x ,不知道是否会用新版本(3.x)

UPDATE

不幸的是,上述解决scheme将无法在Express 3.x中工作,因为express.view将是未定义的

另一个可能的解决scheme是代理response.render函数并设置views文件夹configuration直到获得匹配:

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

我还没有testing过,对我来说也觉得很无奈,不幸的是这个function又被推回去了: https : //github.com/visionmedia/express/pull/1186

更新2

Express 4.10中添加了此function,因为以下拉取请求已合并: https : //github.com/strongloop/express/pull/2320

除了@ user85461答案,require视图部分不适合我。 我做了什么:删除path的东西,并将其全部移动到我可以要求的模块,patch.ViewEnableMultiFolders.js(与当前快递工程):

 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; 

并用于:

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

这是Express 3.x的解决scheme。 它的猴子补丁expression3.x的“视图”对象来执行与上面的@ ShadowCloud解决scheme相同的查找技巧。 不幸的是, View对象的path查找并不干净,因为3.x没有公开它,所以你必须深入到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(); 

但是,您可以将所有视图文件放在“视图”文件夹中,但将每个模块的视图分隔到“视图”文件夹内的自己的文件夹中。 所以,结构是这样的:

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

像往常一样设置视图文件:

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

当为每个模块渲染时,包含模块的名称:

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

甚至是子模块的名称:

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

此解决scheme也可以在版本4.x之前运行,