salix/services/mailer/application/template.js

234 lines
7.7 KiB
JavaScript
Raw Normal View History

2017-05-30 06:06:14 +00:00
var fs = require('fs');
var mustache = require('mustache');
2017-06-07 13:28:42 +00:00
var locale = require('./locale.js');
var inlineCss = require('inline-css');
2017-11-27 14:08:18 +00:00
var path = require('path');
2017-05-30 06:06:14 +00:00
2017-06-07 13:28:42 +00:00
module.exports = {
/**
* Get template.
* @param {String} template - Template name
* @param {Object} countryCode - Language code
* @param {Object} params - Params
* @param {Object} cb - Callback
*/
2017-11-27 14:08:18 +00:00
get: function(template, params, cb) {
var templatePath = path.join(__dirname, 'template', `${template}`, `index.html`);
2017-06-07 13:28:42 +00:00
var classPath = path.join(__dirname, 'template', `${template}`, `${template}.js`);
var stylePath = path.join(__dirname, 'template', `${template}`, 'style.css');
2017-05-30 06:06:14 +00:00
2017-06-07 13:28:42 +00:00
fs.stat(templatePath, (error, stat) => {
if (error)
return cb(new Error('Template ' + template + ' not found'));
2017-05-30 06:06:14 +00:00
2017-06-07 13:28:42 +00:00
let TemplateClass = require(classPath);
let instance = new TemplateClass();
2017-05-31 12:55:41 +00:00
2017-11-27 14:08:18 +00:00
let getRenderedStyles = (error, body) => {
if (error)
return cb(error);
this.renderStyles(stylePath, body, (error, body) => {
2017-11-27 14:08:18 +00:00
if (error)
return cb(error);
// Check if has a subject param
params.subject = params.subject || instance.subject;
2017-11-27 14:08:18 +00:00
if (params.subject == undefined) {
// Try to find a subject from Html source
let title = body.match(new RegExp('<title>(.*?)</title>', 'i'));
if (title)
params.subject = title[1];
}
2017-11-27 14:08:18 +00:00
this.getAttachments(template, body, params.isPreview, (error, result) => {
if (error)
return cb(error);
cb(null, {recipient: instance.recipient, subject: params.subject, body: result.body, attachments: result.attachments});
2017-06-07 13:28:42 +00:00
});
});
};
let getDataCb = () => {
2017-11-27 14:08:18 +00:00
this.render(templatePath, instance, (error, result) => getRenderedStyles(error, result));
};
instance.getData(params, (error, result) => {
if (error)
return cb(error);
locale.load(template, instance.countryCode, (error, result) => {
if (error)
return cb(error);
instance._ = result.locale;
instance.isPreview = params.isPreview;
getDataCb(null, result);
});
2017-05-31 12:55:41 +00:00
});
2017-05-30 06:06:14 +00:00
});
},
/**
* Render template
* @param {String} path - Template path
* @param {Object} data - Params
* @param {Object} cb - Callback
*/
2017-06-07 13:28:42 +00:00
render: function(path, data, cb) {
2017-11-27 14:08:18 +00:00
fs.readFile(path, 'utf8', (error, body) => {
// Find matching sub-templates
let regexp = new RegExp(/\{\{\$\.(.*?)\}\}/, 'ig');
let subTpl = body.match(regexp);
if (!subTpl) {
mustache.parse(body);
return cb(null, mustache.render(body, data));
}
let parentBody = body;
this.renderSub(parentBody, subTpl, data, regexp, (error, body) => {
if (error)
return cb(error);
mustache.parse(body);
cb(null, mustache.render(body, data));
});
});
},
/**
* Render sub-template
* @param {String} body - Raw body
* @param {Object} subTpl - Sub-template name
* @param {Object} data - Params
* @param {Object} regexp - Regexp
* @param {Object} cb - Callback
*/
renderSub: function(body, subTpl, data, regexp, cb) {
let index = 1;
subTpl.forEach(keyName => {
subTplName = keyName.replace(regexp, '$1');
this.get(subTplName, data, (error, result) => {
if (error)
return cb(error);
let subTplBody = result.body;
body = body.replace(keyName, subTplBody);
if (index === subTpl.length)
cb(null, body);
index++;
});
2017-06-07 13:28:42 +00:00
});
},
/**
* Render template style.
* @param {String} path - Stylesheet path
* @param {String} body - Rendered html
* @param {Object} cb - Callback
*/
2017-11-27 14:08:18 +00:00
renderStyles: function(stylePath, html, cb) {
// Common components
let comPath = path.join(__dirname, '../', 'static', 'css', 'component.css');
fs.readFile(comPath, 'utf8', (error, comCss) => {
fs.stat(stylePath, error => {
if (error)
return cb(new Error('Template stylesheet not found'));
fs.readFile(stylePath, 'utf8', (error, css) => {
let style = '<style>' + comCss + css + '</style>';
let body = style + html;
let options = {url: ' '};
inlineCss(body, options)
.then(function(body) {
cb(null, body);
});
});
});
});
},
/**
* Get template attachments
* @param {String} template - Template name
* @param {String} body - template body
* @param {Object} cb - Callback
*/
getAttachments: function(template, body, isPreview, cb) {
let attachments = [];
let tplAttachments = body.match(new RegExp('src="cid:(.*?)"', 'ig'));
2017-06-07 13:28:42 +00:00
2017-11-27 14:08:18 +00:00
if (!tplAttachments)
tplAttachments = {};
// Template default attachments
2017-06-07 13:28:42 +00:00
for (var i = 0; i < tplAttachments.length; i++) {
let src = tplAttachments[i].replace('src="cid:', '').replace('"', '').split('/');
let attachmentTpl = src[0];
let attachment = src[1];
2017-06-07 13:28:42 +00:00
if (isPreview) {
let attachmentPath = `/mailer/static/${attachmentTpl}/${attachment}`;
body = body.replace(tplAttachments[i], `src="${attachmentPath}"`);
} else {
let attachmentPath = path.join(__dirname, 'template', `${attachmentTpl}`, 'image', attachment);
let attachmentName = attachmentTpl + '/' + attachment;
attachments.push({filename: attachmentName, path: attachmentPath, cid: attachmentName});
}
2017-06-07 13:28:42 +00:00
}
if (isPreview)
return cb(null, {body: body, attachments: attachments});
// Template attachment files
let attachmentsPath = path.join(__dirname, 'template', `${template}`, 'attachment.json');
2017-06-07 13:28:42 +00:00
fs.stat(attachmentsPath, (error, stats) => {
if (error)
2017-11-27 14:08:18 +00:00
return cb(null, {body: body, attachments: attachments});
2017-06-07 13:28:42 +00:00
let attachObj = require(attachmentsPath);
2017-06-07 13:28:42 +00:00
for (var i = 0; i < attachObj.length; i++) {
let filename = attachObj[i];
let attachmentPath = path.join(__dirname, 'template', `${template}`, 'attachment', filename);
attachments.push({filename: filename, path: attachmentPath, cid: filename});
2017-06-07 13:28:42 +00:00
}
this.checkAttachments(attachments, error => {
if (error)
return cb(error);
cb(null, {body: body, attachments: attachments});
});
2017-05-30 06:06:14 +00:00
});
},
/**
2017-11-27 14:08:18 +00:00
* Check all template attachments
* @param {Object} attachments - Attachments object
* @param {Object} cb - Callback
*/
checkAttachments: function(attachments, cb) {
for (var i = 0; i < attachments.length; i++) {
var attachment = attachments[i];
fs.stat(attachment.path, error => {
if (error)
return cb(new Error(`Could not load attachment file ${attachment.path}`));
});
}
cb();
2017-05-30 06:06:14 +00:00
}
2017-11-27 14:08:18 +00:00
};