Socket
Socket
Sign inDemoInstall

email-templates

Package Overview
Dependencies
Maintainers
3
Versions
137
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

email-templates - npm Package Compare versions

Comparing version 1.3.0 to 2.0.0-beta

coverage/coverage.json

85

examples/kuemailer/index.js

@@ -39,54 +39,45 @@ /**

*/
var path = require('path'),
templatesDir = path.resolve(__dirname, '..', 'templates'),
emailTemplates = require('../../'),
nodemailer = require('nodemailer'),
kue = require('kue');
var path = require('path')
var templatesDir = path.resolve(__dirname, '..', 'templates')
var EmailTemplate = require('../../').EmailTemplate
var nodemailer = require('nodemailer')
var kue = require('kue')
var EventEmitter = require('events').EventEmitter
var events = require("events");
var deliver = new events.EventEmitter();
var deliver = new EventEmitter()
var jobs = kue.createQueue()
kue.app.listen(3000)
var jobs = kue.createQueue();
kue.app.listen(3000);
jobs.process('postbox', function (job, done) {
deliver.emit(job.data.template, job.data, done)
})
jobs.process('postbox', function(job, done) {
deliver.emit(job.data.template, job.data, done);
});
var template = new EmailTemplate(path.join(templatesDir, 'newsletter'))
var transport = nodemailer.createTransport({
service: 'Gmail',
auth: {
user: 'some-user@gmail.com',
pass: 'some-password'
}
})
deliver.on('newsletter', function (data, done) {
template.render(data.params, function (err, results) {
if (err) return done(err)
emailTemplates(templatesDir, function(err, template) {
if (err) {
console.log(err);
} else {
// Prepare nodemailer transport object
var transport = nodemailer.createTransport("SMTP", {
service: "Gmail",
auth: {
user: "some-user@gmail.com",
pass: "some-password"
transport.sendMail({
from: 'Spicy Meatball <spicy.meatball@spaghetti.com>',
to: data.to,
subject: data.title,
html: results.html,
text: results.text
}, function (err, responseStatus) {
if (err) {
console.error(err)
return done(err)
}
});
template('newsletter', true, function(err, batch) {
deliver.on('newsletter', function(data, done) {
batch(data.params, templatesDir, function(err, html, text) {
transport.sendMail({
from: 'Spicy Meatball <spicy.meatball@spaghetti.com>',
to: data.to,
subject: data.title,
html: html,
text: text
}, function(err, responseStatus) {
if (err) {
console.log(err);
done(err);
} else {
done();
console.log(responseStatus.message);
}
});
});
});
});
}
});
console.log(responseStatus.message)
done()
})
})
})

@@ -6,128 +6,92 @@

var path = require('path')
, templatesDir = path.resolve(__dirname, '..', 'templates')
, emailTemplates = require('../../')
, nodemailer = require('nodemailer');
// // **NOTE**: Did you know `nodemailer` can also be used to send SMTP email through Mandrill, Mailgun, Sendgrid and Postmark?
// <https://github.com/andris9/nodemailer-wellknown#supported-services>
emailTemplates(templatesDir, function(err, template) {
var path = require('path')
var EmailTemplate = require('../../').EmailTemplate
var nodemailer = require('nodemailer')
var wellknown = require('nodemailer-wellknown')
var async = require('async')
var templatesDir = path.resolve(__dirname, '..', 'templates')
var template = new EmailTemplate(path.join(templatesDir, 'newsletter'))
// Prepare nodemailer transport object
var transport = nodemailer.createTransport({
service: 'sendgrid',
auth: {
user: 'some-user@gmail.com',
pass: 'some-password'
}
})
// An example users object with formatted email function
var locals = {
email: 'mamma.mia@spaghetti.com',
name: {
first: 'Mamma',
last: 'Mia'
}
}
// Send a single email
template.render(locals, function (err, results) {
if (err) {
console.log(err);
} else {
return console.error(err)
}
// ## Send a single email
transport.sendMail({
from: 'Spicy Meatball <spicy.meatball@spaghetti.com>',
to: locals.email,
subject: 'Mangia gli spaghetti con polpette!',
html: results.html,
text: results.text
}, function (err, responseStatus) {
if (err) {
return console.error(err)
}
console.log(responseStatus.message)
})
})
// Prepare nodemailer transport object
var transport = nodemailer.createTransport("SMTP", {
service: "Gmail",
auth: {
user: "some-user@gmail.com",
pass: "some-password"
}
});
// ## Send a batch of emails and only load the template once
// An example users object with formatted email function
var locals = {
email: 'mamma.mia@spaghetti.com',
name: {
first: 'Mamma',
last: 'Mia'
}
};
var users = [
{
email: 'pappa.pizza@spaghetti.com',
name: {
first: 'Pappa',
last: 'Pizza'
}
},
{
email: 'mister.geppetto@spaghetti.com',
name: {
first: 'Mister',
last: 'Geppetto'
}
}
]
// Send a single email
template('newsletter', locals, function(err, html, text) {
// Send 10 mails at once
async.mapLimit(users, 10, function (item, next) {
template.render(item, function (err, results) {
if (err) return next(err)
transport.sendMail({
from: 'Spicy Meatball <spicy.meatball@spaghetti.com>',
to: item.email,
subject: 'Mangia gli spaghetti con polpette!',
html: results.html,
text: results.text
}, function (err, responseStatus) {
if (err) {
console.log(err);
} else {
transport.sendMail({
from: 'Spicy Meatball <spicy.meatball@spaghetti.com>',
to: locals.email,
subject: 'Mangia gli spaghetti con polpette!',
html: html,
// generateTextFromHTML: true,
text: text
}, function(err, responseStatus) {
if (err) {
console.log(err);
} else {
console.log(responseStatus.message);
}
});
return next(err)
}
});
// ## Send a batch of emails and only load the template once
// Prepare nodemailer transport object
var transportBatch = nodemailer.createTransport("SMTP", {
service: "Gmail",
auth: {
user: "some-user@gmail.com",
pass: "some-password"
}
});
// An example users object
var users = [
{
email: 'pappa.pizza@spaghetti.com',
name: {
first: 'Pappa',
last: 'Pizza'
}
},
{
email: 'mister.geppetto@spaghetti.com',
name: {
first: 'Mister',
last: 'Geppetto'
}
}
];
// Custom function for sending emails outside the loop
//
// NOTE:
// We need to patch postmark.js module to support the API call
// that will let us send a batch of up to 500 messages at once.
// (e.g. <https://github.com/diy/trebuchet/blob/master/lib/index.js#L160>)
var Render = function(locals) {
this.locals = locals;
this.send = function(err, html, text) {
if (err) {
console.log(err);
} else {
transportBatch.sendMail({
from: 'Spicy Meatball <spicy.meatball@spaghetti.com>',
to: locals.email,
subject: 'Mangia gli spaghetti con polpette!',
html: html,
// generateTextFromHTML: true,
text: text
}, function(err, responseStatus) {
if (err) {
console.log(err);
} else {
console.log(responseStatus.message);
}
});
}
};
this.batch = function(batch) {
batch(this.locals, templatesDir, this.send);
};
};
// Load the template and send the emails
template('newsletter', true, function(err, batch) {
for(var user in users) {
var render = new Render(users[user]);
render.batch(batch);
}
});
next(null, responseStatus.message)
})
})
}, function (err) {
if (err) {
console.error(err)
}
});
console.log('Succesfully sent %d messages', users.length)
})

@@ -9,3 +9,3 @@

// **NOTE**: Did you know `nodemailer` can also be used to send SMTP email through Postmark?
// <https://github.com/andris9/Nodemailer#well-known-services-for-smtp>
// <https://github.com/andris9/nodemailer-wellknown#supported-services>

@@ -15,109 +15,81 @@ // For more message format options, see Postmark's developer documentation section:

var path = require('path')
, templatesDir = path.resolve(__dirname, '..', 'templates')
, emailTemplates = require('../../')
, postmark = require('postmark')('your-api-key');
var path = require('path')
var EmailTemplate = require('../../').EmailTemplate
var postmark = require('postmark')
var _ = require('lodash')
emailTemplates(templatesDir, function(err, template) {
var templatesDir = path.resolve(__dirname, '..', 'templates')
var client = new postmark.Client('your-server-key')
if (err) {
console.log(err);
} else {
var locals = {
email: 'mamma.mia@spaghetti.com',
name: {
first: 'Mamma',
last: 'Mia'
}
}
// ## Send a single email
var template = new EmailTemplate(path.join(templatesDir, 'newsletter'))
// An example users object with formatted email function
var locals = {
email: 'mamma.mia@spaghetti.com',
name: {
first: 'Mamma',
last: 'Mia'
}
};
// Send a single email
template(locals, function (err, results) {
if (err) {
return console.error(err)
}
client.sendEmail({
From: 'Spicy Meatball <spicy.meatball@spaghetti.com>',
To: locals.email,
Subject: 'Mangia gli spaghetti con polpette!',
HtmlBody: results.html,
TextBody: results.text
}, function (err, response) {
if (err) {
console.error(err.status)
console.error(err.message)
return
}
console.log(response)
})
})
// Send a single email
template('newsletter', locals, function(err, html, text) {
if (err) {
console.log(err);
} else {
postmark.send({
From: 'Spicy Meatball <spicy.meatball@spaghetti.com>',
To: locals.email,
Subject: 'Mangia gli spaghetti con polpette!',
HtmlBody: html,
TextBody: text
}, function(err, response) {
if (err) {
console.log(err.status);
console.log(err.message);
} else {
console.log(response);
}
});
}
});
// Send a batch of emails and only load the template once
var users = [
{
email: 'pappa.pizza@spaghetti.com',
name: {
first: 'Pappa',
last: 'Pizza'
}
},
{
email: 'mister.geppetto@spaghetti.com',
name: {
first: 'Mister',
last: 'Geppetto'
}
}
]
// ## Send a batch of emails and only load the template once
// An example users object
var users = [
{
email: 'pappa.pizza@spaghetti.com',
name: {
first: 'Pappa',
last: 'Pizza'
}
},
{
email: 'mister.geppetto@spaghetti.com',
name: {
first: 'Mister',
last: 'Geppetto'
}
// use promises this time. Use your favorite library such as bluebird
// or use the native Promise included in node > 0.12 and io.js
Promise.all(_.map(users, function (user) {
return template.render(user)
.then(function (results) {
return {
From: 'Spicy Meatball <spicy.meatball@spaghetti.com>',
To: user.email,
Subject: 'Mangia gli spaghetti con polpette!',
HtmlBody: results.html,
TextBody: results.text
}
];
})
}))
.then(function (messages) {
client.sendEmailBatch(messages, function (err, batchResults) {
// Throwing inside a promise will just reject the promise
// not stop your server
if (err) throw err
// Custom function for sending emails outside the loop
//
// NOTE:
// We need to patch postmark.js module to support the API call
// that will let us send a batch of up to 500 messages at once.
// (e.g. <https://github.com/diy/trebuchet/blob/master/lib/index.js#L160>)
var Render = function(locals) {
this.locals = locals;
this.send = function(err, html, text) {
if (err) {
console.log(err);
} else {
postmark.send({
From: 'Spicy Meatball <spicy.meatball@spaghetti.com>',
To: locals.email,
Subject: 'Mangia gli spaghetti con polpette!',
HtmlBody: html,
TextBody: text
}, function(err, response) {
if (err) {
console.log(err.status);
console.log(err.message);
} else {
console.log(response);
}
});
}
};
this.batch = function(batch) {
batch(this.locals, templatesDir, this.send);
};
};
// Load the template and send the emails
template('newsletter', true, function(err, batch) {
for(var user in users) {
var render = new Render(users[user]);
render.batch(batch);
}
});
}
});
console.info('Messages sent to postmark')
})
})

@@ -1,2 +0,1 @@

module.exports = require('./lib/main');
module.exports = require('./lib/main')

@@ -1,256 +0,75 @@

// node-email-templates
// Copyright (c) 2012 Nick Baugh <niftylettuce@gmail.com>
// MIT Licensed
'use strict';
// Node.js module for rendering beautiful emails with [ejs][1] templates
// and email-friendly inline CSS using [juice][2].
Object.defineProperty(exports, '__esModule', {
value: true
});
// * Author: [@niftylettuce](https://twitter.com/#!/niftylettuce)
// * Source: <https://github.com/niftylettuce/node-email-templates>
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
// # node-email-templates
var _util = require('./util');
var path = require('path')
, fs = require('fs')
, async = require('async')
, juice = require('juice')
, glob = require('glob')
, zlib = require('zlib')
, _ = require('lodash')
, tm = require('./templateManager')
var _lodash = require('lodash');
var validBufferTypes = [ 'deflate', 'deflateRaw', 'gzip' ]
var _emailTemplate = require('./email-template');
// # Email Template
var EmailTemplate = function(templateDirectory, defaults, done) {
var _emailTemplate2 = _interopRequireDefault(_emailTemplate);
if (typeof defaults === 'function') done = defaults;
var _debug = require('debug');
var that = this;
var _debug2 = _interopRequireDefault(_debug);
this.render = function(locals, templatePath, html, text, stylesheet, bufferType, callback) {
// Check if `bufferType` is a function (callback), or string
var isBuffer = false
if (typeof bufferType === 'function') {
callback = bufferType
} else if (typeof bufferType === 'string') {
// Ensure that `bufferType` is a valid `zlib` compression type
if (_.contains(validBufferTypes, bufferType)) {
throw new Error('`zlib.' + bufferType + '` does not exist or is not a valid buffer type')
} else {
isBuffer = true
}
}
var _path = require('path');
// Check if `bufferType` is not an empty string, so we'll use the
// global bufferType instead.
if (this.bufferType !== '') {
isBuffer = true
bufferType = this.bufferType
}
var _consolidate = require('consolidate');
if (typeof html === 'function') {
callback = html;
html = this.html;
}
if (!html) html = this.html
if (!text) text = this.text
if (!stylesheet) stylesheet = this.stylesheet
locals = _.defaults(locals, (typeof defaults === 'object') ? defaults : {});
locals.templatePath = this.templatePath
var debug = (0, _debug2['default'])('email-templates:creator');
// Configure options for template and stylesheet files.
var htmlOpts = { source: html, locals: locals }
, textOpts = { source: text, locals: locals }
, cssOpts = { source: stylesheet, locals: locals };
htmlOpts.filename = glob.sync(path.join(locals.templatePath, '*html.*'))[0];
textOpts.filename = glob.sync(path.join(locals.templatePath, '*text.*'))[0];
cssOpts.filename = glob.sync(path.join(locals.templatePath, '*style.*'))[0];
// Render all templates and stylesheets.
async.map([htmlOpts, textOpts, cssOpts], tm.render.bind(tm), function(err, results) {
if (err) return callback(err)
html = results[0]
text = results[1]
stylesheet = results[2]
// Make a copy of the juiceOptions object so we can add the stylesheet.
var juiceOptions = (typeof locals.juiceOptions === 'object' ? _.assign({}, locals.juiceOptions) : {})
juiceOptions.extraCss = (juiceOptions.extraCss || "") + stylesheet
// Inject available styles into HTML.
html = (stylesheet) ? juice(html, juiceOptions) : html
// Return a compressed buffer if needed.
if (isBuffer) {
async.map([ new Buffer(html), new Buffer(text) ], zlib[bufferType], function(err, buffers) {
if (err) return callback(err)
html = buffers[0]
text = buffers[1]
callback(null, html, text)
})
}else {
callback(null, html, text)
}
})
};
// Ensure the `templateDirectory` is not undefined
if (typeof templateDirectory === 'undefined')
function exportable(templateDirectory, options, done) {
if ((0, _lodash.isFunction)(options)) {
done = options;
options = {};
}
if (!templateDirectory) {
return done(new Error('templateDirectory is undefined'));
}
// Ensure the `templateDirectory` is a valid directory path
fs.stat(templateDirectory, function(err, stats) {
return (0, _util.ensureDirectory)(templateDirectory, function (err) {
if (err) return done(err);
debug('Creating Email Templates in %s', (0, _path.basename)(templateDirectory));
return done(null, template(templateDirectory, options));
});
}
if (err) return done(new Error(err));
function template(templateDirectory, options) {
return function _template(directory, locals, callback) {
if ((0, _lodash.isFunction)(locals)) {
callback = locals;
locals = {};
}
locals = (0, _lodash.defaults)(locals, options);
if (directory == null) {
return callback(new Error('templateName was not defined'));
}
if (!stats.isDirectory())
return done(new Error('templateDirectory is not a valid directory path'));
done(null, function(templateName, locals, bufferType, callback) {
var scopeInfo = {
'templatePath': '',
'stylesheet': '',
'text': '',
'html': '',
'bufferType':''
};
// Check if `bufferType` is a function (callback), or string
var isBuffer = false
if (typeof bufferType === 'function') {
callback = bufferType
} else if (typeof bufferType === 'string') {
// Ensure that `bufferType` is a valid `zlib` compression type
if (_.contains(validBufferTypes, bufferType)) {
throw new Error('`zlib.' + bufferType + '` does not exist or is not a valid buffer type')
} else {
isBuffer = true
}
}
// Fallback if user doesn't pass all the args
var batchEmail = false;
if (typeof locals !== 'undefined' && typeof locals === 'function') {
callback = locals;
locals = {};
} else if (typeof callback !== 'undefined' && typeof callback === 'function') {
if (typeof locals === 'undefined' || !locals instanceof Object) {
locals = {};
} else if (locals === true) {
// We are trying to load the template into memory, but not render it
// This lets us send batches of emails using the same template
// and we only are loading the assets once
batchEmail = true;
}
}
// Batch load function
var batchCheck = function() {
if (batchEmail) {
if (isBuffer) scopeInfo.bufferType = bufferType
return callback(null, that.render.bind(scopeInfo));
}
if (isBuffer) {
that.render.call(scopeInfo, locals, templatePath, null, null, null, bufferType, callback);
} else {
that.render.call(scopeInfo, locals, templatePath, null, null, null, callback);
}
};
// Ensure the `templateName` is valid
if (templateName === undefined) return callback('templateName was not defined');
// Set the full path to the template
var templatePath = scopeInfo.templatePath = path.join(templateDirectory, templateName);
// Ensure the `templateName` is a valid directory path
fs.stat(templatePath, function(err, stats) {
if (err) return callback(err);
if (!stats.isDirectory())
return callback(templatePath + ' is not a valid directory path');
// Ensure that at least an html file exists inside
scopeInfo.html = glob.sync(templatePath + '/*html.*')[0] || '';
fs.stat(scopeInfo.html, function(err, stats) {
if (err) return callback(err);
if (!stats.isFile()) return callback(scopeInfo.html + ' is not a valid file path');
// Read the html file
fs.readFile(scopeInfo.html, 'utf8', function(err, data) {
if (err) return callback(err);
if (data === '') return callback(scopeInfo.html + ' was an empty file');
else scopeInfo.html = data;
// Set asset paths
scopeInfo.text = glob.sync(templatePath + '/*text.*')[0] || '';
scopeInfo.stylesheet = glob.sync(templatePath + '/*style.*')[0] || '';
async.map([scopeInfo.text, scopeInfo.stylesheet], checkExists, function(err, results) {
if (err) return callback(err);
if (!results[0]) scopeInfo.text = false
if (!results[1]) scopeInfo.stylesheet = false
if (scopeInfo.text && scopeInfo.stylesheet) {
async.map([scopeInfo.text, scopeInfo.stylesheet], fs.readFile, function(err, results) {
if (err) return callback(err);
results[0] = results[0].toString('utf8');
results[1] = results[1].toString('utf8');
if (results[0] === '') scopeInfo.text = false;
if (results[1] === '') scopeInfo.stylesheet = false;
scopeInfo.text = results[0];
scopeInfo.stylesheet = results[1];
batchCheck();
});
} else if (scopeInfo.text && !scopeInfo.stylesheet) {
fs.readFile(scopeInfo.text, 'utf8', function(err, data) {
if (err) return callback(err);
if (data === '') return callback(scopeInfo.text + ' was empty');
scopeInfo.text = data;
batchCheck();
});
} else if (!scopeInfo.text && scopeInfo.stylesheet) {
fs.readFile(scopeInfo.stylesheet, 'utf8', function(err, data) {
if (err) return callback(err);
if (data === '') return callback(scopeInfo.stylesheet + ' was empty');
scopeInfo.stylesheet = data;
batchCheck();
});
} else {
batchCheck();
}
});
});
var et = new _emailTemplate2['default']('' + templateDirectory + '/' + directory);
if (locals === true) {
return callback(null, function (locals, dir, next) {
et.render(locals, function (err, result) {
result = result || {};
next(err, result.html, result.text);
});
});
});
function checkExists(item, callback) {
function cb(exists) {
return callback(null, exists)
}
// node >= v0.8.x
if (fs.exists) return fs.exists(item, cb)
// other versions of node fallback to path.exists
return path.exists(item, cb)
}
et.render(locals, function (err, result) {
result = result || {};
callback(err, result.html, result.text);
});
};
}
});
};
exportable.EmailTemplate = _emailTemplate2['default'];
exportable.requires = _consolidate.requires;
module.exports = function(templateDirectory, defaults, done) {
return new EmailTemplate(templateDirectory, defaults, done);
};
exports['default'] = exportable;
module.exports = exports['default'];
{
"name": "email-templates",
"description": "Node.js module for rendering beautiful emails with ejs, jade, swig, hbs, or handlebars templates and email-friendly inline CSS using juice.",
"version": "1.3.0",
"version": "2.0.0-beta",
"author": "Nick Baugh <niftylettuce@gmail.com>",

@@ -53,35 +53,41 @@ "contributors": [

"scripts": {
"prepublish": "npm prune",
"test": "mocha --reporter spec --bail --require test/support/should test/",
"test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --reporter dot --require test/support/should test/",
"test-travis": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --reporter spec --require test/support/should test/"
"prepublish": "npm run compile && npm prune",
"compile": "babel src --modules common --out-dir lib",
"watch": "babel src --watch --modules common --out-dir lib",
"test": "mocha",
"test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --reporter dot",
"test-travis": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly"
},
"dependencies": {
"bluebird": "^2.9.25",
"consolidate": "^0.12.0",
"debug": "^2.2.0",
"glob": "^5.0.0",
"juice": "^1.0.0",
"consolidate": "^0.11.0",
"async": "^0.9.0",
"lodash": "^3.5.0",
"glob": "^4.0.0"
"lodash": "^3.5.0"
},
"devDependencies": {
"nodemailer": "^0.3.44",
"postmark": "^0.1.8",
"mocha": "^2.1.0",
"async": "^0.9.0",
"babel": "^5.4.3",
"chai": "^2.0.0",
"mkdirp": "^0.3.5",
"rimraf": "^2.2.8",
"ejs": "^1.0.0",
"swig": "^1.3.2",
"dustjs-linkedin": "^2.4.0",
"ejs": "^2.3.0",
"handlebars": "^3.0.0",
"istanbul": "^0.3.2",
"jade": "^1.3.1",
"handlebars": "^1.3.0",
"emblem": "~0.3.16",
"dustjs-linkedin": "^2.4.0",
"less": "^1.7.0",
"stylus": "^0.45.1",
"styl": "^0.2.7",
"less": "^2.5.0",
"mkdirp": "^0.5.1",
"mocha": "^2.1.0",
"node-sass": "^3.1.1",
"nodemailer": "^1.3.4",
"nodemailer-wellknown": "^0.1.5",
"postmark": "^1.0.0",
"rimraf": "^2.2.8",
"sinon": "^1.10.2",
"sinon-chai": "^2.7.0",
"istanbul": "^0.3.2"
"styl": "^0.2.7",
"stylus": "^0.51.1",
"swig": "^1.3.2"
},
"license": "MIT",
"bugs": {

@@ -88,0 +94,0 @@ "url": "https://github.com/niftylettuce/node-email-templates/issues/new"

@@ -11,2 +11,3 @@

[![Gitter][gitter-image]][gitter-url]
[![js-standard-style][standard-image]][standard-url]

@@ -56,7 +57,2 @@ Node.js NPM package for rendering beautiful emails with your template engine and CSS pre-processor of choice coupled with email-friendly inline CSS using [juice][juice].

This module depends on [jsdom](https://github.com/tmpvar/jsdom) which requires the ability to compile C++ on your localhost. Before installing, please verify that you have the prerequisites installed for your OS.
* [OSX requirements](https://github.com/tmpvar/jsdom#mac)
* [Linux requirements](https://github.com/tmpvar/jsdom#linux)
#### Important Note for Windows Users

@@ -72,9 +68,6 @@

```bash
npm install -S email-templates
```
Install `email-templates` and the engines you wish to use by adding them to your `package.json` dependencies.
> Starting with version `1.1.1` you must install the engines you wish to use by adding them to your `package.json` dependencies.
```bash
npm install --save email-templates
npm install -S [ejs|jade|swig|handlebars|emblem|dust-linkedin]

@@ -89,29 +82,23 @@ ```

```bash
npm install -S email-templates
npm install --save email-templates@2
```
2. Install the template engine you intend to use:
- `ejs@^1.0.0`
- `jade@^1.3.1`
- `swig@^1.3.2`
- `handlebars@^1.3.0`
- `emblem@~0.3.16`
- `dust-linkedin@^2.4.0`
- `less@^1.7.0`
- `stylus@^^0.45.1`
- `styl@^0.2.7`
- `node-sass@^3.1.1`
- `ejs@^2.0.0`
- `jade@^1.9.0`
- `swig@^1.4.2`
- `handlebars@^3.0.0`
- `dust-linkedin@^2.7.0`
```bash
npm install -S <engine>
```
- `less@^2.5.0`
- `stylus@^^0.51.0`
- `styl@^0.2.9`
- `node-sass@^3.0.0`
3. Create a folder called `templates` inside your root directory (or elsewhere).
```bash
mkdir templates
npm install --save <engine>
```
4. For each of your email templates (e.g. a welcome email to send to users when they register on your site), respectively name and create a folder inside the `templates` folder.
3. For each of your email templates (e.g. a welcome email to send to users when they register on your site), respectively name and create a folder.

@@ -122,3 +109,3 @@ ```bash

5. Add the following files inside the template's folder:
4. Add the following files inside the template's folder:
* `html.{{ext}}` (**required**)

@@ -132,7 +119,5 @@ * `text.{{ext}}` (**optional**)

6. You may use the `include` directive from [ejs][ejs] (for example, to include a common header or footer). See the `/examples` folder for details.
5. You may use the `include` directive from [ejs][ejs] (for example, to include a common header or footer). See the `/examples` folder for details.
7. Utilize one of the examples below for your respective email module and start sending beautiful emails!
## Template Engine Options

@@ -144,9 +129,7 @@

```js
// ...
emailTemplates(templatesDir, { open: '{{', close: '}}' }, function(err, template) {
// ...
```javascript
emailTemplates(templatesDir, { delimiter: '?' }, function (err, template) {
```
> You can also pass <a href="https://github.com/visionmedia/ejs#options" target="_blank">other options from EJS's documentation</a>.
> You can also pass <a href="https://github.com/mde/ejs#options" target="_blank">other options from EJS's documentation</a>.

@@ -174,2 +157,34 @@ Want to add a helper or partial to Handlebars?

Render a single template (having only loaded the template once).
```js
var EmailTemplate = require('email-templates').EmailTemplate
var path = require('path')
var templateDir = path.join(__dirname, 'templates', 'newsletter')
var newsletter = new EmailTemplate(templateDir)
var user = {name: 'Joe', pasta: 'spaghetti'}
newsletter.render(user, function (err, results) {
// result.html
// result.text
})
var async = require('async')
var users = [
{name: 'John', pasta: 'Rigatoni'},
{name: 'Luca', pasta: 'Tortellini'}
]
async.each(users, function (user, next) {
newsletter.render(user, function (err, results) {
if (err) return next(err)
// result.html
// result.text
})
}, function (err) {
//
})
```
Render a template for a single email or render multiple (having only loaded the template once).

@@ -179,4 +194,4 @@

var path = require('path')
, templatesDir = path.join(__dirname, 'templates')
, emailTemplates = require('email-templates');
var templatesDir = path.join(__dirname, 'templates')
var emailTemplates = require('email-templates');

@@ -236,258 +251,6 @@ emailTemplates(templatesDir, function(err, template) {

### [Nodemailer][nodemailer]
### More
```js
var path = require('path')
, templatesDir = path.resolve(__dirname, '..', 'templates')
, emailTemplates = require('email-templates')
, nodemailer = require('nodemailer');
Please check the [examples directory](https://github.com/niftylettuce/node-email-templates/tree/master/examples)
emailTemplates(templatesDir, function(err, template) {
if (err) {
console.log(err);
} else {
// ## Send a single email
// Prepare nodemailer transport object
var transport = nodemailer.createTransport("SMTP", {
service: "Gmail",
auth: {
user: "some-user@gmail.com",
pass: "some-password"
}
});
// An example users object with formatted email function
var locals = {
email: 'mamma.mia@spaghetti.com',
name: {
first: 'Mamma',
last: 'Mia'
}
};
// Send a single email
template('newsletter', locals, function(err, html, text) {
if (err) {
console.log(err);
} else {
transport.sendMail({
from: 'Spicy Meatball <spicy.meatball@spaghetti.com>',
to: locals.email,
subject: 'Mangia gli spaghetti con polpette!',
html: html,
// generateTextFromHTML: true,
text: text
}, function(err, responseStatus) {
if (err) {
console.log(err);
} else {
console.log(responseStatus.message);
}
});
}
});
// ## Send a batch of emails and only load the template once
// Prepare nodemailer transport object
var transportBatch = nodemailer.createTransport("SMTP", {
service: "Gmail",
auth: {
user: "some-user@gmail.com",
pass: "some-password"
}
});
// An example users object
var users = [
{
email: 'pappa.pizza@spaghetti.com',
name: {
first: 'Pappa',
last: 'Pizza'
}
},
{
email: 'mister.geppetto@spaghetti.com',
name: {
first: 'Mister',
last: 'Geppetto'
}
}
];
// Custom function for sending emails outside the loop
//
// NOTE:
// We need to patch postmark.js module to support the API call
// that will let us send a batch of up to 500 messages at once.
// (e.g. <https://github.com/diy/trebuchet/blob/master/lib/index.js#L160>)
var Render = function(locals) {
this.locals = locals;
this.send = function(err, html, text) {
if (err) {
console.log(err);
} else {
transportBatch.sendMail({
from: 'Spicy Meatball <spicy.meatball@spaghetti.com>',
to: locals.email,
subject: 'Mangia gli spaghetti con polpette!',
html: html,
// generateTextFromHTML: true,
text: text
}, function(err, responseStatus) {
if (err) {
console.log(err);
} else {
console.log(responseStatus.message);
}
});
}
};
this.batch = function(batch) {
batch(this.locals, templatesDir, this.send);
};
};
// Load the template and send the emails
template('newsletter', true, function(err, batch) {
for(var user in users) {
var render = new Render(users[user]);
render.batch(batch);
}
});
}
});
```
### [Postmark][postmark]
This example utilizes [Postmark.js][postmarkjs].
> Did you know `nodemailer` can also be used to send SMTP email through Postmark? See [this section][nodemailer-smtp] of their Readme for more info.
For more message format options, see [this section][postmark-msg-format] of Postmark's developer documentation section.
```js
var path = require('path')
, templatesDir = path.resolve(__dirname, '..', 'templates')
, emailTemplates = require('email-templates')
, postmark = require('postmark')('your-api-key');
emailTemplates(templatesDir, function(err, template) {
if (err) {
console.log(err);
} else {
// ## Send a single email
// An example users object with formatted email function
var locals = {
email: 'mamma.mia@spaghetti.com',
name: {
first: 'Mamma',
last: 'Mia'
}
};
// Send a single email
template('newsletter', locals, function(err, html, text) {
if (err) {
console.log(err);
} else {
postmark.send({
From: 'Spicy Meatball <spicy.meatball@spaghetti.com>',
To: locals.email,
Subject: 'Mangia gli spaghetti con polpette!',
HtmlBody: html,
TextBody: text
}, function(err, response) {
if (err) {
console.log(err.status);
console.log(err.message);
} else {
console.log(response);
}
});
}
});
// ## Send a batch of emails and only load the template once
// An example users object
var users = [
{
email: 'pappa.pizza@spaghetti.com',
name: {
first: 'Pappa',
last: 'Pizza'
}
},
{
email: 'mister.geppetto@spaghetti.com',
name: {
first: 'Mister',
last: 'Geppetto'
}
}
];
// Custom function for sending emails outside the loop
//
// NOTE:
// We need to patch postmark.js module to support the API call
// that will let us send a batch of up to 500 messages at once.
// (e.g. <https://github.com/diy/trebuchet/blob/master/lib/index.js#L160>)
var Render = function(locals) {
this.locals = locals;
this.send = function(err, html, text) {
if (err) {
console.log(err);
} else {
postmark.send({
From: 'Spicy Meatball <spicy.meatball@spaghetti.com>',
To: locals.email,
Subject: 'Mangia gli spaghetti con polpette!',
HtmlBody: html,
TextBody: text
}, function(err, response) {
if (err) {
console.log(err.status);
console.log(err.message);
} else {
console.log(response);
}
});
}
};
this.batch = function(batch) {
batch(this.locals, templatesDir, this.send);
};
};
// Load the template and send the emails
template('newsletter', true, function(err, batch) {
for(user in users) {
var render = new Render(users[user]);
render.batch(batch);
}
});
}
});
```
## Conventions
See [nifty-conventions][nifty-conventions] for code guidelines, general project requirements, and git workflow.
## Contributors

@@ -545,1 +308,3 @@

[transactional-email-templates]: https://github.com/mailgun/transactional-email-templates
[standard-image]: https://img.shields.io/badge/code%20style-standard-brightgreen.svg?style=flat
[standard-url]: https://github.com/feross/standard

@@ -1,13 +0,13 @@

var tm = require('../lib/templateManager')
, path = require('path')
, expect = require('chai').expect
, fs = require('fs')
, tmpDir = path.join(__dirname, '..', '.tmproj')
, mkdirp = require('mkdirp')
, rimraf = require('rimraf')
/* global describe it beforeEach afterEach */
var tm = require('../src/template-manager')
var path = require('path')
var expect = require('chai').expect
var fs = require('fs')
var tmpDir = path.join(__dirname, '..', '.test-templates')
var mkdirp = require('mkdirp')
var rimraf = require('rimraf')
describe('Template manager', function() {
/////////////////////////////////////////////////////////////////////////////
describe('Template manager', function () {
// Setup
beforeEach(function(done) {
beforeEach(function (done) {
// Setup a tmp directory for test files.

@@ -17,3 +17,3 @@ mkdirp(tmpDir, done)

afterEach(function(done) {
afterEach(function (done) {
// Destroy all test files.

@@ -23,5 +23,4 @@ rimraf(tmpDir, done)

/////////////////////////////////////////////////////////////////////////////
// Tests
it('should render ejs', function(done) {
it('should render ejs', function (done) {
var opts = {

@@ -33,5 +32,5 @@ locals: {item: 'test'},

tm.render(opts, function(err, res) {
expect(err).to.be.null;
expect(res).to.equal('<h1>test .ejs</h1>');
tm.render(opts.filename, opts.source, opts.locals, function (err, res) {
expect(err).to.be.null
expect(res).to.equal('<h1>test .ejs</h1>')

@@ -46,10 +45,9 @@ done()

item: 'test',
open: '{{',
close: '}}'
delimiter: '?'
},
filename: 'test.ejs',
source: '<h1>{{=item}} {{=engine}}</h1>'
source: '<h1><?=item?> <?=engine?></h1>'
}
tm.render(opts, function(err, res) {
tm.render(opts.filename, opts.source, opts.locals, function (err, res) {
expect(err).to.be.null

@@ -61,3 +59,3 @@ expect(res).to.equal('<h1>test .ejs</h1>')

it('should render jade', function(done) {
it('should render jade', function (done) {
var opts = {

@@ -69,5 +67,5 @@ locals: {item: 'test'},

tm.render(opts, function(err, res) {
expect(err).to.be.null;
expect(res).to.equal('<h1>test</h1><h1>.jade</h1>');
tm.render(opts.filename, opts.source, opts.locals, function (err, res) {
expect(err).to.be.null
expect(res).to.equal('<h1>test</h1><h1>.jade</h1>')

@@ -78,3 +76,3 @@ done()

it('should render swig', function(done) {
it('should render swig', function (done) {
var opts = {

@@ -86,5 +84,5 @@ locals: {item: 'test'},

tm.render(opts, function(err, res) {
expect(err).to.be.null;
expect(res).to.equal('<h1>test .swig</h1>');
tm.render(opts.filename, opts.source, opts.locals, function (err, res) {
expect(err).to.be.null
expect(res).to.equal('<h1>test .swig</h1>')

@@ -95,3 +93,3 @@ done()

it('should render handlebars', function(done) {
it('should render handlebars', function (done) {
var opts = {

@@ -103,5 +101,5 @@ locals: {item: 'test'},

tm.render(opts, function(err, res) {
expect(err).to.be.null;
expect(res).to.equal('<h1>test .handlebars</h1>');
tm.render(opts.filename, opts.source, opts.locals, function (err, res) {
expect(err).to.be.null
expect(res).to.equal('<h1>test .handlebars</h1>')

@@ -112,3 +110,3 @@ done()

it ('should render handlebars with helpers', function(done) {
it('should render handlebars with helpers', function (done) {
var opts = {

@@ -118,9 +116,9 @@ locals: {

helpers: {
uppercase: function(context) {return context.toUpperCase()}
uppercase: function (context) {return context.toUpperCase()}
}
},
filename: 'test.hbs',
source: '<h1>{{uppercase item}} {{engine}}</h1>',
source: '<h1>{{uppercase item}} {{engine}}</h1>'
}
tm.render(opts, function(err, res) {
tm.render(opts.filename, opts.source, opts.locals, function (err, res) {
expect(err).to.be.null

@@ -132,20 +130,5 @@ expect(res).to.equal('<h1>TEST .hbs</h1>')

it('should render emblem', function(done) {
it('should render dust', function (done) {
var opts = {
locals: {item: 'test'},
filename: 'test.emblem',
source: 'h1 {{ item }}\nh1 {{ engine }}'
}
tm.render(opts, function(err, res) {
expect(err).to.be.null;
expect(res).to.equal('<h1>test</h1><h1>.emblem</h1>');
done()
})
})
it('should render dust', function(done) {
var opts = {
locals: {item: 'test'},
filename: 'test.dust',

@@ -155,5 +138,5 @@ source: '<h1>{item}\n</h1><h1>{engine}</h1>'

tm.render(opts, function(err, res) {
expect(err).to.be.null;
expect(res).to.equal('<h1>test</h1><h1>.dust</h1>');
tm.render(opts.filename, opts.source, opts.locals, function (err, res) {
expect(err).to.be.null
expect(res).to.equal('<h1>test</h1><h1>.dust</h1>')

@@ -164,12 +147,12 @@ done()

it('should render less', function(done) {
it('should render less', function (done) {
var opts = {
locals : {},
filename : 'test.less',
source : '.class{ width: (1 + 1) }'
locals: {},
filename: 'test.less',
source: '.class{ width: (1 + 1) }'
}
tm.render(opts, function(err, res) {
expect(err).to.be.null;
expect(res).to.equal('.class {\n width: 2;\n}\n');
tm.render(opts.filename, opts.source, opts.locals, function (err, res) {
expect(err).to.be.null
expect(res).to.equal('.class {\n width: 2;\n}\n')

@@ -180,3 +163,3 @@ done()

it('should render less with @import statement', function(done) {
it('should render less with @import statement', function (done) {
var testMainLessFile = path.join(tmpDir, 'main.less')

@@ -190,10 +173,10 @@ var testIncludesFile = path.join(tmpDir, 'includes.less')

var opts = {
locals : {},
filename : testMainLessFile,
source : fs.readFileSync(testMainLessFile).toString()
locals: {},
filename: testMainLessFile,
source: fs.readFileSync(testMainLessFile).toString()
}
tm.render(opts, function(err, res) {
expect(err).to.be.null;
expect(res).to.equal('.body {\n color: #333333;\n}\n');
tm.render(opts.filename, opts.source, opts.locals, function (err, res) {
expect(err).to.be.null
expect(res).to.equal('.body {\n color: #333333;\n}\n')

@@ -204,22 +187,22 @@ done()

it('should render stylus', function(done) {
var opts = {locals: {}};
opts.filename = 'test.stylus';
opts.source = 'body\n width: 2px\n';
tm.render(opts, function(err, res) {
expect(err).to.be.null;
expect(res).to.equal('body {\n width: 2px;\n}\n');
done();
it('should render stylus', function (done) {
var opts = {locals: {}}
opts.filename = 'test.stylus'
opts.source = 'body\n width: 2px\n'
tm.render(opts.filename, opts.source, opts.locals, function (err, res) {
expect(err).to.be.null
expect(res).to.equal('body {\n width: 2px;\n}\n')
done()
})
})
it('should render styl', function(done) {
it('should render styl', function (done) {
var opts = {
locals : {whitespace: true},
filename : 'test.styl',
source : 'body\n color: blue'
locals: {whitespace: true},
filename: 'test.styl',
source: 'body\n color: blue'
}
tm.render(opts, function(err, res) {
expect(err).to.be.null;
tm.render(opts.filename, opts.source, opts.locals, function (err, res) {
expect(err).to.be.null
expect(res).to.equal('body {\n color: blue;\n}')

@@ -230,12 +213,12 @@ done()

it('should render sass', function(done) {
it('should render sass', function (done) {
var opts = {
locals : {},
filename : 'test.sass',
source : '$gray: #ccc;body {color: $gray}'
locals: {},
filename: 'test.sass',
source: '$gray: #ccc;body {color: $gray}'
}
tm.render(opts, function(err, res) {
expect(err).to.be.null;
expect(res).to.equal('body {\n color: #ccc; }\n');
tm.render(opts.filename, opts.source, opts.locals, function (err, res) {
expect(err).to.be.null
expect(res).to.equal('body {\n color: #ccc; }\n')

@@ -246,12 +229,12 @@ done()

it('should render css', function(done) {
it('should render css', function (done) {
var opts = {
locals : {},
filename : 'test.css',
source : 'body { color: #ccc; }'
locals: {},
filename: 'test.css',
source: 'body { color: #ccc; }'
}
tm.render(opts, function(err, res) {
expect(err).to.be.null;
expect(res).to.equal('body { color: #ccc; }');
tm.render(opts.filename, opts.source, opts.locals, function (err, res) {
expect(err).to.be.null
expect(res).to.equal('body { color: #ccc; }')

@@ -258,0 +241,0 @@ done()

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc