rc@73
|
1 /**
|
rc@73
|
2 * Module dependencies.
|
rc@73
|
3 */
|
rc@73
|
4
|
rc@73
|
5 var path = require('path');
|
rc@73
|
6 var fs = require('fs');
|
rc@73
|
7 var utils = require('./utils');
|
rc@73
|
8 var dirname = path.dirname;
|
rc@73
|
9 var basename = path.basename;
|
rc@73
|
10 var extname = path.extname;
|
rc@73
|
11 var exists = fs.existsSync || path.existsSync;
|
rc@73
|
12 var join = path.join;
|
rc@73
|
13
|
rc@73
|
14 /**
|
rc@73
|
15 * Expose `View`.
|
rc@73
|
16 */
|
rc@73
|
17
|
rc@73
|
18 module.exports = View;
|
rc@73
|
19
|
rc@73
|
20 /**
|
rc@73
|
21 * Initialize a new `View` with the given `name`.
|
rc@73
|
22 *
|
rc@73
|
23 * Options:
|
rc@73
|
24 *
|
rc@73
|
25 * - `defaultEngine` the default template engine name
|
rc@73
|
26 * - `engines` template engine require() cache
|
rc@73
|
27 * - `root` root path for view lookup
|
rc@73
|
28 *
|
rc@73
|
29 * @param {String} name
|
rc@73
|
30 * @param {Object} options
|
rc@73
|
31 * @api private
|
rc@73
|
32 */
|
rc@73
|
33
|
rc@73
|
34 function View(name, options) {
|
rc@73
|
35 options = options || {};
|
rc@73
|
36 this.name = name;
|
rc@73
|
37 this.root = options.root;
|
rc@73
|
38 var engines = options.engines;
|
rc@73
|
39 this.defaultEngine = options.defaultEngine;
|
rc@73
|
40 var ext = this.ext = extname(name);
|
rc@73
|
41 if (!ext && !this.defaultEngine) throw new Error('No default engine was specified and no extension was provided.');
|
rc@73
|
42 if (!ext) name += (ext = this.ext = ('.' != this.defaultEngine[0] ? '.' : '') + this.defaultEngine);
|
rc@73
|
43 this.engine = engines[ext] || (engines[ext] = require(ext.slice(1)).__express);
|
rc@73
|
44 this.path = this.lookup(name);
|
rc@73
|
45 }
|
rc@73
|
46
|
rc@73
|
47 /**
|
rc@73
|
48 * Lookup view by the given `path`
|
rc@73
|
49 *
|
rc@73
|
50 * @param {String} path
|
rc@73
|
51 * @return {String}
|
rc@73
|
52 * @api private
|
rc@73
|
53 */
|
rc@73
|
54
|
rc@73
|
55 View.prototype.lookup = function(path){
|
rc@73
|
56 var ext = this.ext;
|
rc@73
|
57
|
rc@73
|
58 // <path>.<engine>
|
rc@73
|
59 if (!utils.isAbsolute(path)) path = join(this.root, path);
|
rc@73
|
60 if (exists(path)) return path;
|
rc@73
|
61
|
rc@73
|
62 // <path>/index.<engine>
|
rc@73
|
63 path = join(dirname(path), basename(path, ext), 'index' + ext);
|
rc@73
|
64 if (exists(path)) return path;
|
rc@73
|
65 };
|
rc@73
|
66
|
rc@73
|
67 /**
|
rc@73
|
68 * Render with the given `options` and callback `fn(err, str)`.
|
rc@73
|
69 *
|
rc@73
|
70 * @param {Object} options
|
rc@73
|
71 * @param {Function} fn
|
rc@73
|
72 * @api private
|
rc@73
|
73 */
|
rc@73
|
74
|
rc@73
|
75 View.prototype.render = function(options, fn){
|
rc@73
|
76 this.engine(this.path, options, fn);
|
rc@73
|
77 };
|