-
Notifications
You must be signed in to change notification settings - Fork 312
/
Copy pathviewEngine.js
94 lines (79 loc) · 2.66 KB
/
viewEngine.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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
var path = require('path'),
_ = require('underscore'),
layoutTemplates = {};
module.exports = exports = ViewEngine;
function ViewEngine(options) {
this.options = options || {};
/**
* Ensure `render` is bound to this instance, because it can be passed around.
*/
this.render = this.render.bind(this);
}
ViewEngine.prototype.render = function render(viewPath, data, callback) {
var app, layoutData;
data.locals = data.locals || {};
app = data.app;
layoutData = _.extend({}, data, {
body: this.getViewHtml(viewPath, data.locals, app),
appData: app.toJSON(),
bootstrappedData: this.getBootstrappedData(data.locals, app),
_app: app
});
this.renderWithLayout(layoutData, app, callback);
};
/**
* Render with a layout.
*/
ViewEngine.prototype.renderWithLayout = function renderWithLayout(locals, app, callback) {
this.getLayoutTemplate(app, function(err, templateFn) {
if (err) return callback(err);
var html = templateFn(locals);
callback(null, html);
});
};
/**
* Cache layout template function.
*/
ViewEngine.prototype.getLayoutTemplate = function getLayoutTemplate(app, callback) {
var baseLayoutName = this.getBaseLayoutName(app);
if (layoutTemplates[app.options.entryPath]) {
return callback(null, layoutTemplates[app.options.entryPath]);
}
app.templateAdapter.getLayout(baseLayoutName, app.options.entryPath, function(err, template) {
if (err) return callback(err);
layoutTemplates[app.options.entryPath] = template;
callback(err, template);
});
};
ViewEngine.prototype.getBaseLayoutName = function getBaseLayoutName(app) {
return app.options.baseLayoutName ? app.options.baseLayoutName : '__layout';
};
ViewEngine.prototype.getViewHtml = function getViewHtml(viewPath, locals, app) {
var basePath = path.join('app', 'views'),
BaseView = require('../shared/base/view'),
name,
View,
view;
locals = _.clone(locals);
// Pass in the app.
locals.app = app;
name = viewPath.substr(viewPath.indexOf(basePath) + basePath.length + 1);
View = BaseView.getView(name, app.options.entryPath);
view = new View(locals);
return view.getHtml();
};
ViewEngine.prototype.getBootstrappedData = function getBootstrappedData(locals, app) {
var bootstrappedData = {};
_.each(locals, function(modelOrCollection, name) {
if (app.modelUtils.isModel(modelOrCollection) || app.modelUtils.isCollection(modelOrCollection)) {
bootstrappedData[name] = {
summary: app.fetcher.summarize(modelOrCollection),
data: modelOrCollection.toJSON()
};
}
});
return bootstrappedData;
};
ViewEngine.prototype.clearCachedLayouts = function () {
layoutTemplates = {};
};