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