sidebars
Version:
Asynchronous sidebar / widget execution library
236 lines (176 loc) • 5.14 kB
JavaScript
;
var _ = require('underscore');
var Step = require('step');
var EventEmitter = require('events').EventEmitter;
var handlebars = require('handlebars');
var fs = require('fs');
var debug = require('./plugins/debug');
var sidebars = module.exports = {
debug: debug,
plugins: [],
engine_cb: null,
handlebars: function (path, options, cb) {
if (path === null) {
cb(null, '');
return;
}
Step(
function read () {
fs.readFile( path, this );
},
function compile (err, template_str) {
if (err) {
return cb(err, '');
}
var template = handlebars.compile(template_str.toString());
var html = template( options );
cb(null, html);
}
);
},
engine: function (cb) {
this.engine_cb = cb;
return this;
},
use: function (plugin) {
if (! _.isUndefined(plugin) && ! _.isUndefined(plugin.register)) {
this.plugins.push(plugin);
plugin.register(this);
}
return this;
},
render: function (req, res, next, page) {
var self = this;
var widgets = {};
var sidebars;
/*
* Check if template engine is set, if not set handlebars
*/
if (_.isNull(this.engine_cb)) {
this.engine_cb = this.handlebars;
}
/*
* Check if a template was provided
*/
if (_.isUndefined(page.template)) {
next();
return;
}
/*
* Check for sidebars.
*/
if (_.isUndefined(page.sidebars)) {
this.engine_cb( page.template, {}, function (err, html) {
if (err) {
next(err);
} else {
res.send(html);
}
});
return;
} else {
sidebars = page.sidebars;
}
/*
* Process template and sidebars
*/
Step(
function loadWidgets () {
_.each(sidebars, function (sidebar) {
_.each(sidebar, function (widget) {
try {
if (_.isUndefined(widget.package)) {
self.emit('warn', { msg: 'Widget package isUndefined.', widget: widget, req: req });
return;
}
if (_.isUndefined(widgets[ widget.package ])) {
widgets[ widget.package ] = require( widget.package );
}
} catch (e) {
self.emit('err', { error: e, widget: widget, req: req });
}
});
});
return null;
},
function executeWidgets () {
var group = this.group();
_.each(sidebars, function (sidebar) {
_.each(sidebar, function (widget) {
var groupFn = group();
try {
if (_.isUndefined(widget.package) || _.isUndefined(widgets[ widget.package ]) ) {
// We thru the warning in loadWidgets for this.
groupFn(null, null);
} else if (! _.isUndefined(widgets[ widget.package ].execute)) {
widgets[ widget.package ].execute(widget.params, req, groupFn);
} else {
self.emit('warn', { msg: 'Method execute isUndefined.', widget: widget, req: req });
groupFn(null, null);
}
}
catch (e) {
self.emit('err', { error: e, widget: widget, req: req });
groupFn(null, null);
}
});
});
},
function renderWidgets (err, widget_data) {
if (err) {
next(err);
return false;
}
var group = this.group();
var index = -1;
_.each(sidebars, function (sidebar, sidebar_name) {
_.each(sidebar, function (widget) {
index++;
if (widget_data[index] === null) {
self.engine_cb(null, null, group());
return;
}
if (_.isUndefined(widget_data[index].template)) {
self.engine_cb(null, null, group());
return;
}
if (_.isUndefined(widget_data[index].data)) {
self.engine_cb(null, null, group());
return;
}
self.engine_cb(
widget_data[index].template,
widget_data[index].data,
group()
);
});
});
},
function renderTemplate (err, template_data) {
var html = {};
var index = 0;
_.each(sidebars, function (sidebar, sidebar_name) {
_.each(sidebar, function (widget) {
if (_.isUndefined(html[sidebar_name])) {
html[sidebar_name] = '';
}
html[sidebar_name] += template_data[index++];
});
});
self.engine_cb(
page.template,
html,
this
);
},
function send (err, html) {
if (err) {
next(err);
} else {
res.send(html);
}
}
);
}
};
_.extend(sidebars, EventEmitter.prototype);