forked from YahooArchive/express-view
-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
79 lines (66 loc) · 2.64 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
/*
* Copyright (c) 2013, Yahoo! Inc. All rights reserved.
* Copyrights licensed under the New BSD License.
* See the accompanying LICENSE file for terms.
*/
/*jslint node: true, nomen: true */
'use strict';
var View = require('./lib/view'),
debug = require('debug')('express:view');
function expressView(app) {
// storing a reference to the original view class
// implementation so we can fallback to that if
// there is not a synthetic template available
var OrignalViewClass = app.get('view');
if (app['@view']) { return app; }
// Brand.
Object.defineProperty(app, '@view', {
value: expressView
});
function ViewShim(name, options) {
var v, o;
if (!app.get('locator')) {
debug('Call `app.set("locator", locatorObj)` before listening for traffic on the `express` app.');
throw new Error('Locator instance should be mounted');
}
options = options || {};
options.locator = app.get('locator');
options.layout = app.get('layout');
v = new View(name, options);
// piping the important pieces to shim the view instance
this.name = v.name;
this.path = v.path;
this.render = function (opts, fn) {
// trying to render with the view implementation that relies on
// synthetic views from locator. this render process is sync,
// that's why we have a giant try/catch here.
try {
v.render(opts, function (err) {
if (err) {
debug('Failed to lookup synthetic view "%s" thru `locator`', name);
// fallback to the original implementation (which might be cacheable)
// TODO: the following line might throw, what should we do?
if (!o || !opts.cache) {
o = new OrignalViewClass(name, options);
}
if (!o.path) {
throw new Error('Failed to lookup view "' + name + '"');
}
// render using the original implemented from express which
// is going to try to use the filesystem and the view engines
o.render(opts, fn);
return;
}
fn.apply(this, arguments);
});
} catch (err) {
err.view = v;
fn(err);
}
};
}
// Modifies the Express `app`.
app.set('view', ViewShim);
return app;
}
exports.extend = expressView;