sheercms
Version:
Sheer Cliff CMS is a simple and powerful content management system (CMS) for Node JS.
484 lines (446 loc) • 15.4 kB
JavaScript
var logger = require('../logger');
var models = require('./templates-models');
var api = require('../api');
var mongoose = require('mongoose');
var dust = require('dustjs-linkedin');
var S = require('string');
var util = require('../utilities');
var contentModels = require('../content/content-models');
var _templates = [];
//disable the whitespace compression
dust.optimizers.format = function(ctx, node) { return node };
/*
callback: (err)
*/
module.exports.loadTemplates = function(callback) {
models.Template.find().sort({name:1}).exec(function (err, templates) {
if (err) {
if (callback) callback(err);
}
else {
try {
if (templates) {
_templates = mapTemplates(templates, true);
for (var i = 0; i < _templates.length; i++) {
var t = _templates[i];
compileTemplate(t.viewText, t.key);
}
if (callback) callback(null);
}
else {
var e = new Error("No templates were found.");
logger.error(e);
if (callback) callback(e);
}
} catch(e) {
logger.error(e);
if (callback) callback(e);
}
}
});
};
function mapTemplates(templates, allProps) {
var arr = [];
for(var i = 0; i < templates.length; i++) {
var t = templates[i];
arr.push(mapTemplate(t, allProps));
}
return arr;
}
function mapTemplate(template, allProps) {
var obj = {
id: template.id.toString(),
_id: template._id.toString(),
name: template.name,
key: template.key,
desc: template.desc,
created: template.created,
modified: template.modified,
createdBy: template.createdBy,
modifiedBy: template.modifiedBy,
icon: template.icon,
cacheSeconds: template.cacheSeconds
};
if (allProps) {
obj.viewText = template.viewText;
}
return obj;
}
function compileTemplate(text, key) {
try {
logger.info("Compiling template: " + key);
var compiled = dust.compile(text, key);
dust.loadSource(compiled);
return "";
}
catch(e) {
logger.error("Error compiling template. Key=" + key + "; Error=" + e);
return e.toString();
}
}
function getTemplate(id) {
for(var i = 0; i < _templates.length; i++) {
if (_templates[i].id == id)
return _templates[i];
}
return null;
}
function getTemplateByName(name) {
for(var i = 0; i < _templates.length; i++) {
if (_templates[i].name === name)
return _templates[i];
}
return null;
}
/*
Renders the template with this key
callback: (err, output)
*/
module.exports.render = function(key, model, callback) {
try {
var keyName;
if (typeof key == 'object') //mongoose.Types.ObjectId
{
var t = getTemplate(key);
if (t)
keyName = t.key;
else {
var e = new Error("Template not found: " + key);
logger.error(e);
if (callback) callback(e);
return;
}
}
else
keyName = key;
if (!model)
model = {};
model.funks = require('./dust-functions');
logger.debug("Rendering DUST template: " + keyName);
dust.render(keyName, model, function (err, out) {
if (err) {
logger.error(err);
if (callback) callback(err);
}
else if (out) {
if (callback) callback(null, out);
}
else {
var e = new Error("Render output is null.");
logger.error(e);
if (callback) callback(e);
}
});
}
catch(e) {
logger.error(e);
if (callback) callback(e);
}
};
/*
callback: (err, template)
*/
module.exports.save = function(template, username, callback) {
try {
if (template._id) {
//existing item
tId = getObjectId(template._id);
models.Template.findById(tId, function (err, result) {
if (err) {
logger.error(err);
if (callback) callback(err);
}
else if (result == null) {
var e = new Error("Template not found: " + template._id);
logger.error(e);
if (callback) callback(e);
}
else {
if (S(template.icon).isEmpty())
template.icon = '/cms/static/images/icons/32/page_white.png';
//update the properties
result.name = template.name;
result.modified = new Date();
result.modifiedBy = username,
result.key = template.key || template.name;
result.desc = template.desc;
result.icon = template.icon;
result.viewText = template.viewText;
result.cacheSeconds = template.cacheSeconds;
try {
result.save(function (err) {
try {
if (err) {
logger.error(err);
if (callback) callback(err);
}
else {
module.exports.loadTemplates(function (err) {
if (err) {
if (callback) callback(err);
}
else {
if (callback) callback(null, mapTemplate(result, true));
}
});
}
}
catch(e) {
logger.error(e);
if (callback) callback(e);
}
});
} catch (e) {
logger.error(e);
if (callback) callback(e);
}
}
});
}
else {
var key = template.key || template.name;
//first make sure there isn't already one with this unique key
models.Template.findOne({ key: key}, function (err, result) {
if (err) {
logger.error(err);
if (callback) callback(err);
}
else if (result) {
var e = new Error("A template with this key already exists: " + key);
logger.error(e);
if (callback) callback(e);
}
else {
if (S(template.icon).isEmpty())
template.icon = '/cms/static/images/icons/32/page_white.png';
//new template
var t = new models.Template({
name: template.name,
key: key,
created: new Date(),
createdBy: username,
desc: template.desc,
icon: template.icon,
viewText: template.viewText,
cacheSeconds: template.cacheSeconds
});
try {
t.save(function (err) {
try {
if (err) {
logger.error(err);
if (callback) callback(err);
}
else {
module.exports.loadTemplates(function (err) {
if (err) {
if (callback) callback(err);
}
else {
if (callback) callback(null, mapTemplate(t, true));
}
});
}
}
catch(e) {
logger.error(e);
if (callback) callback(e);
}
});
}
catch (e) {
logger.error(e);
if (callback) callback(e);
}
}
});
}
}
catch(e) {
logger.error(e);
if (callback) callback(e);
}
};
/*
callback: (err, template)
*/
module.exports.importTemplate = function(template, username, reload, callback) {
try {
//the template should have an ID
if (!template.id) {
var e = new Error('The id property is required during import.');
logger.error(e);
if (callback) callback(e);
return;
}
logger.info("Importing template: " + template.id);
var id = util.toObjectId(template.id);
models.Template.findById(id, function(err, doc) {
if (err) {
logger.error(err);
if (callback) callback(err);
}
else {
if (!doc) {
doc = new models.Template();
doc._id = template.id;
doc.created = new Date();
doc.createdBy = username;
}
//update the properties
doc.name = template.name;
doc.modified = new Date();
doc.modifiedBy = username,
doc.key = template.key || template.name;
doc.desc = template.desc;
doc.icon = template.icon;
doc.viewText = template.viewText;
doc.cacheSeconds = template.cacheSeconds;
try {
doc.save(function (err) {
try {
if (err) {
logger.error(err);
if (callback) callback(err);
}
else {
if (reload === true) {
module.exports.loadTemplates(function (err) {
if (err) {
if (callback) callback(err);
}
else {
if (callback) callback(null, mapTemplate(doc, true));
}
});
}
else {
if (callback) callback(null, mapTemplate(doc, true));
}
}
}
catch(e) {
logger.error(e);
if (callback) callback(e);
}
});
}
catch (e) {
logger.error(e);
if (callback) callback(e);
}
}
});
}
catch(e) {
logger.error(e);
if (callback) callback(e);
}
}
/*
callback: (err, template)
*/
module.exports.getTemplate = function(id, callback) {
if (callback) {
try {
logger.debug('templates-api.getTemplate: ' + id);
tId = getObjectId(id);
callback(null, getTemplate(tId));
}
catch (e) {
logger.error(e);
callback(e);
}
}
};
module.exports.getTemplateSync = function(id) {
tId = getObjectId(id);
return getTemplate(tId);
};
module.exports.getTemplateByName = function(name, callback) {
if (callback) {
try {
logger.debug('templates-api.getTemplateByName: ' + name);
callback(null, getTemplateByName(name));
}
catch(e) {
logger.error(e);
callback(e);
}
}
};
/*
callback: (err, templates)
*/
module.exports.getTemplates = function(allProps, callback) {
if (callback) {
try {
if (allProps)
callback(null, _templates);
else
callback(null, mapTemplates(_templates, false));
}
catch (e) {
logger.error(e);
callback(e);
}
}
};
/*
callback: (err)
*/
module.exports.delete = function(id, callback) {
try {
if (typeof id == 'string')
id = mongoose.Types.ObjectId(id);
//first make sure there are no items using the template
contentModels.Draft.find({templateId: id}).count(function (err, count) {
try {
if (err) {
if (callback) callback(err);
}
else if (count === 0) {
models.Template.findByIdAndRemove(id, function (err) {
try {
if (err) {
logger.error(err);
if (callback) callback(err);
}
else {
//rebuilt the templates cache
module.exports.loadTemplates(function (err) {
if (err) {
if (callback) callback(err);
}
else {
if (callback) callback(null);
}
});
}
}
catch(e) {
logger.error(e);
if (callback) callback(e);
}
});
}
else {
var e = new Error('This template cannot be deleted because there are content items using it.');
logger.error(e);
if (callback) callback(e);
}
}
catch(e) {
logger.error(e);
if (callback) callback(e);
}
});
}
catch(e) {
logger.error(e);
if (callback) callback(e);
}
};
function getObjectId(id) {
return util.toObjectId(id);
}