UNPKG

rendr

Version:

Render your Backbone.js apps on the client and the server.

95 lines (79 loc) 2.72 kB
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 = {}; };