2014-02-19 114 views
50

我想在调用res.render()时更改Express的视图文件夹。例如,如果我在/folder/file.js文件中调用res.render(viewName),我希望该Express可以查看/ folder/views中的视图。根据调用res.render()的文件的位置更改Express视图文件夹

如果该文件是内部/folder1/folder2/file.js,我想表达查找内部/资料夹/文件夹2 /视图

是否有可能有何看法?

回答

67

您可以使用方法set()重新定义express的默认设置。

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

对于动态路径的变化,你可以做这样的事情:

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); 
+3

它看起来不错,但我怎样才能使它的动态?如果两个用户同时访问不同的路径,其中一个app.set会覆盖另一个,不是吗? – Talysson

+0

你能指点我关于app.get('view')的文档吗?我似乎无法找到它。我在这里看不到“视图”:http://expressjs.com/en/api.html#app.settings.table。我不喜欢使用无证函数的想法。 – Nuzzolilo

28

而不是简单地通过你的视图名称到渲染功能,你可以通过相对或绝对路径。

简单的例子:

app.get('/your/path', function(req, res) { 
    //viewname can include or omit the filename extension 
    res.render(__dirname + '/folder/with/views/viewname')); 
}); 
+3

这似乎waaaay比重写渲染功能更容易! – stone

+1

它确实! – Connor

2

这很简单

改变快速的查看文件夹时,一个叫res.render(), 刚刚成立,其中的观点所在的路径, 在你的情况,

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

这改变了Express将搜索指定视图的路径。

1

您还可以通过使用require.resolve得到的相对路径: res.render(require.resolve('./folder/with/views/viewname'));

+0

这是正确的方式,谢谢! – mathieug

0

(对不起,我不能发表评论还)

@nuzzolilo's answer效果很好。但是,如果你喜欢ES6

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

这只是提高了代码的可读性;)