expressjs条件视图渲染路径

时间:2013-11-30 17:36:09

标签: javascript node.js express pug function-overriding

我正在使用expressjs编写应用程序。我的观点通常是 / views 文件夹。它们覆盖了我90%的客户需求,但有时我必须覆盖其中一个或另一个视图以添加自定义功能。我真的很想知道我可以建立一个文件夹结构,如:

*{ ...other expressjs files and folders...}*
/views
    view1.jade
    view2.jade
    view2.jade
/customerA
    view2.jade
/customerB
    view3.jade

我想要的是覆盖expressjs' response.render() 函数的行为以应用以下算法:

1. a customer requests a view
2. if /{customer_folder}/{view_name}.jade exists, than
       render /{customer_folder}/{view_name}.jade
   else
       render /views/{view_name}.jade

因此,对于 customerA response.render('view1') 将引用 /views/view1.jade ,而 response.render('view2') 将引用 / customerA / view2.jade (使用appcelerator的钛的人可能听起来很熟悉)

我想要一种优雅的方式来实现这种行为,而无需修改expressjs核心功能的麻烦,因此可能会在升级我的框架时得到处理。我想这是一个常见的问题,但我在网上找不到任何文章。

2 个答案:

答案 0 :(得分:2)

我会创建一个自定义View类:

var express = require('express');
var app     = express();
var View    = app.get('view');

var MyView  = function(name, options) {
  View.call(this, name, options);
};
MyView.prototype = Object.create(View.prototype);
MyView.prototype.lookup = function(path) {
  // `path` contains the template name to look up, so here you can perform
  // your customer-specific lookups and change `path` so that it points to
  // the correct file for the customer...
  ...

  // when done, just call the original lookup method.
  return View.prototype.lookup.call(this, path);
};
app.set('view', MyView);

答案 1 :(得分:-1)

您可以挂钩http.ServerResponse.render

这是我头脑中的一些代码,用作中间件:

var backup = res.render
res.render = function() {
    //Do your thing with the arguments array, maybe use environment variables
    backup.apply(res, arguments) //Function.prototype.apply calls a function in context of argument 1, with argument 2 being the argument array for the actual call
}