Skip to content

Commit

Permalink
Merge b7161e4 into ab02fe4
Browse files Browse the repository at this point in the history
  • Loading branch information
snow01 committed Oct 12, 2015
2 parents ab02fe4 + b7161e4 commit cb7b030
Show file tree
Hide file tree
Showing 6 changed files with 141 additions and 37 deletions.
50 changes: 29 additions & 21 deletions README.md
Expand Up @@ -12,8 +12,11 @@

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].

> Enjoy this package? Check out [eskimo][eskimo] and [express-cdn][express-cdn], and follow [@niftylettuce](http://twitter.com/niftylettuce)!
> Enjoy this package? Follow [@yeliahs](https://twitter.com/yeliahs)!
## Note

This package (v2) is extended version of [email-templates](https://github.com/niftylettuce/node-email-templates). v2 adds support for templating subjects.

## Index

Expand All @@ -34,7 +37,7 @@ For customizable, pre-built email templates, see [Email Blueprints][email-bluepr

#### Supported Template Engines

node-email-templates uses [consolidate.js][consolidate], and therefore supports a vast array of template modules. Please see [consolidate.js][consolidate] for the impressive full list.
email-templates-v2 uses [consolidate.js][consolidate], and therefore supports a vast array of template modules. Please see [consolidate.js][consolidate] for the impressive full list.

#### Supported CSS Pre-processors

Expand All @@ -56,10 +59,10 @@ Developing on OS X or Ubuntu/Linux is recommended, but if you only have access t

## Installation

Install `email-templates` and the engines you wish to use by adding them to your `package.json` dependencies.
Install `email-templates-v2` and the engines you wish to use by adding them to your `package.json` dependencies.

```bash
npm install --save email-templates
npm install --save email-templates-v2
# See https://www.npmjs.com/package/consolidate for a full list of available template engines
npm install -S [ejs|jade|nunjucks|handlebars|emblem|dust-linkedin]
```
Expand All @@ -70,7 +73,7 @@ npm install -S [ejs|jade|nunjucks|handlebars|emblem|dust-linkedin]
1. Install the module for your respective project:

```bash
npm install --save email-templates@2
npm install --save email-templates-v2@2
```

2. Install the template engine you intend to use:
Expand Down Expand Up @@ -98,13 +101,14 @@ npm install -S [ejs|jade|nunjucks|handlebars|emblem|dust-linkedin]
```

4. Add the following files inside the template's folder:
* `html.{{ext}}` (**required**)
* `text.{{ext}}` (**optional**)
* `style.{{ext}}`(**optional**)
* `html.{{ext}}` (**required**) - for html format of email
* `text.{{ext}}` (**optional**) - for text format of email
* `style.{{ext}}`(**optional**) - styles for html format
* `subject.{{ext}}`(**optional**) - for subject of email

> **See [supported template engines](#supported-template-engines) for possible template engine extensions (e.g. `.ejs`, `.jade`, `.nunjucks`) to use for the value of `{{ext}}` above.**
> You may prefix any file name with anything you like to help you identify the files more easily in your IDE. The only requirement is that the filename contains `html.`, `text.`, and `style.` respectively.
> You may prefix any file name with anything you like to help you identify the files more easily in your IDE. The only requirement is that the filename contains `html.`, `text.`, `style.`, and `subject.` respectively.
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.

Expand Down Expand Up @@ -172,6 +176,7 @@ async.each(users, function (user, next) {
if (err) return next(err)
// result.html
// result.text
// result.subject
})
}, function (err) {
//
Expand Down Expand Up @@ -211,14 +216,16 @@ Promise.all(templates)
.then(function (results) {
console.log(results[0].html)
console.log(results[0].text)
console.log(results[0].subject)
console.log(results[1].html)
console.log(results[1].text)
console.log(results[1].subject)
})
```

### More

Please check the [examples directory](https://github.com/niftylettuce/node-email-templates/tree/master/examples)
Please check the [examples directory](https://github.com/snow01/node-email-templates-v2/tree/master/examples)

## Contributors

Expand All @@ -228,6 +235,7 @@ Please check the [examples directory](https://github.com/niftylettuce/node-email
* Jason Sims <sims.jrobert@gmail.com>
* Miguel Mota <hello@miguelmota.com>
* Jeduan Cornejo <jeduan@gmail.com>
* Shailendra Sharma <shailendra.sharma@gmail.com>

> Full list of contributors can be found on the [GitHub Contributor Graph][gh-graph]
Expand All @@ -252,17 +260,17 @@ Please check the [examples directory](https://github.com/niftylettuce/node-email
[express-cdn]: https://github.com/niftylettuce/express-cdn
[license-image]: http://img.shields.io/badge/license-MIT-blue.svg?style=flat
[license-url]: LICENSE
[gh-graph]: https://github.com/niftylettuce/node-email-templates/graphs/contributors
[npm-image]: http://img.shields.io/npm/v/email-templates.svg?style=flat
[npm-url]: https://npmjs.org/package/email-templates
[npm-downloads]: http://img.shields.io/npm/dm/email-templates.svg?style=flat
[travis-url]: http://travis-ci.org/niftylettuce/node-email-templates
[travis-image]: http://img.shields.io/travis/niftylettuce/node-email-templates.svg?style=flat
[codeclimate-image]: http://img.shields.io/codeclimate/github/niftylettuce/node-email-templates.svg?style=flat
[codeclimate-url]: https://codeclimate.com/github/niftylettuce/node-email-templates?branch=master
[coveralls-image]: https://img.shields.io/coveralls/niftylettuce/node-email-templates.svg?style=flat
[coveralls-url]: https://coveralls.io/r/niftylettuce/node-email-templates?branch=master
[gitter-url]: https://gitter.im/niftylettuce/node-email-templates
[gh-graph]: https://github.com/snow01/node-email-templates-v2/graphs/contributors
[npm-image]: http://img.shields.io/npm/v/email-templates-v2.svg?style=flat
[npm-url]: https://npmjs.org/package/email-templates-v2
[npm-downloads]: http://img.shields.io/npm/dm/email-templates-v2.svg?style=flat
[travis-url]: http://travis-ci.org/snow01/node-email-templates-v2
[travis-image]: http://img.shields.io/travis/snow01/node-email-templates-v2.svg?style=flat
[codeclimate-image]: http://img.shields.io/codeclimate/github/snow01/node-email-templates-v2.svg?style=flat
[codeclimate-url]: https://codeclimate.com/github/snow01/node-email-templates-v2?branch=master
[coveralls-image]: https://img.shields.io/coveralls/snow01/node-email-templates-v2.svg?style=flat
[coveralls-url]: https://coveralls.io/r/snow01/node-email-templates-v2?branch=master
[gitter-url]: https://gitter.im/snow01/node-email-templates-v2
[gitter-image]: http://img.shields.io/badge/chat-online-brightgreen.svg?style=flat
[eskimo]: http://eskimo.io
[nifty-conventions]: https://github.com/niftylettuce/nifty-conventions
Expand Down
22 changes: 15 additions & 7 deletions package.json
@@ -1,9 +1,13 @@
{
"name": "email-templates",
"name": "email-templates-v2",
"description": "Node.js module for rendering beautiful emails with ejs, jade, swig, hbs, or handlebars templates and email-friendly inline CSS using juice.",
"version": "2.0.1",
"author": "Nick Baugh <niftylettuce@gmail.com>",
"version": "2.0.2",
"author": "Shailendra Sharma <shailendra.sharma@gmail.com>",
"contributors": [
{
"name": "Shailendra Sharma",
"email": "shailendra.sharma@gmail.com"
},
{
"name": "Nick Baugh",
"email": "niftylettuce@gmail.com"
Expand Down Expand Up @@ -38,12 +42,16 @@
"email-templates",
"juice",
"inline",
"css"
"css",
"subject template",
"html template",
"text template",
"v2"
],
"homepage": "https://github.com/niftylettuce/node-email-templates",
"homepage": "https://github.com/snow01/node-email-templates-v2",
"repository": {
"type": "git",
"url": "https://github.com/niftylettuce/node-email-templates.git"
"url": "https://github.com/snow01/node-email-templates-v2.git"
},
"engines": {
"node": ">= 0.10"
Expand Down Expand Up @@ -97,6 +105,6 @@
},
"license": "MIT",
"bugs": {
"url": "https://github.com/niftylettuce/node-email-templates/issues/new"
"url": "https://github.com/snow01/node-email-templates-v2/issues/new"
}
}
27 changes: 22 additions & 5 deletions src/email-template.js
Expand Up @@ -29,11 +29,11 @@ export default class EmailTemplate {
}

_loadTemplates () {
return P.map(['html', 'text', 'style'], (type) => {
return P.map(['html', 'text', 'style', 'subject'], (type) => {
return readContents(this.path, type)
})
.then((files) => {
let [html, text, style] = files
let [html, text, style, subject] = files

if (!html && !text) {
let err = new Error(`Neither html nor text template files found or are both empty in path ${this.dirname}`)
Expand All @@ -56,6 +56,11 @@ export default class EmailTemplate {
}
this.files.style = style

if (subject) {
debug('Found subject %s in %s', basename(subject.filename), this.dirname)
}
this.files.subject = subject

debug('Finished loading template')
})
}
Expand All @@ -71,6 +76,17 @@ export default class EmailTemplate {
.nodeify(callback)
}

renderSubject (locals, callback) {
debug('Rendering subject')
return this._init()
.then(() => {
if (!this.files.subject) return null
return renderFile(this.files.subject, locals)
})
.tap(() => debug('Finished rendering subject'))
.nodeify(callback)
}

renderHtml (locals, callback) {
debug('Rendering HTML')
return this._init()
Expand Down Expand Up @@ -101,12 +117,13 @@ export default class EmailTemplate {

return P.all([
this.renderHtml(locals),
this.renderText(locals)
this.renderText(locals),
this.renderSubject(locals)
])
.then((rendered) => {
let [html, text] = rendered
let [html, text, subject] = rendered
return {
html, text
html, text, subject
}
})
.nodeify(callback)
Expand Down
4 changes: 2 additions & 2 deletions src/main.js
Expand Up @@ -38,14 +38,14 @@ function template (templateDirectory, options) {
return callback(null, function (locals, dir, next) {
et.render(locals, function (err, result) {
result = result || {}
next(err, result.html, result.text)
next(err, result.html, result.text, result.subject)
})
})
}

et.render(locals, function (err, result) {
result = result || {}
callback(err, result.html, result.text)
callback(err, result.html, result.text, result.subject)
})
}
}
Expand Down
73 changes: 72 additions & 1 deletion test/testMain.js
Expand Up @@ -67,6 +67,26 @@ describe('Email templates', function () {
})
})

it('html, text, and subject files', function (done) {
var html = '<h4><%= item%></h4>'
var text = '<%= item%>'
var subject = 'Hello <%= item%>'
fs.writeFileSync(path.join(templateDir, templateName, 'html.ejs'), html)
fs.writeFileSync(path.join(templateDir, templateName, 'text.ejs'), text)
fs.writeFileSync(path.join(templateDir, templateName, 'subject.ejs'), subject)

emailTemplates(templateDir, function (err, template) {
expect(err).to.be.null
template(templateName, {item: 'test'}, function (err, html, text, subject) {
expect(err).to.be.null
expect(html).to.equal('<h4>test</h4>')
expect(text).to.equal('test')
expect(subject).to.equal('Hello test')
done()
})
})
})

it('html and text files with custom names', function (done) {
var html = '<h4><%= item%></h4>'
var text = '<%= item%>'
Expand All @@ -84,6 +104,26 @@ describe('Email templates', function () {
})
})

it('html, text, and subject files with custom names', function (done) {
var html = '<h4><%= item%></h4>'
var text = '<%= item%>'
var subject = 'Hello <%= item%>'
fs.writeFileSync(path.join(templateDir, templateName, 'custom-filename-html.ejs'), html)
fs.writeFileSync(path.join(templateDir, templateName, 'custom-filename-text.ejs'), text)
fs.writeFileSync(path.join(templateDir, templateName, 'custom-filename-subject.ejs'), subject)

emailTemplates(templateDir, function (err, template) {
expect(err).to.be.null
template(templateName, {item: 'test'}, function (err, html, text, subject) {
expect(err).to.be.null
expect(html).to.equal('<h4>test</h4>')
expect(text).to.equal('test')
expect(subject).to.equal('Hello test')
done()
})
})
})

it('html with style element and juiceOptions', function (done) {
var html = '<style> h4 { color: red; }</style><h4><%= item%></h4>'
var css = 'h4 { color: blue; }'
Expand Down Expand Up @@ -129,7 +169,7 @@ describe('Email templates', function () {

it('html(jade) with inline CSS(less)', function (done) {
var html = 'h4= item'
var css = '@color: #ccc; h4 { color: @color }'
var css = '@color: #cccccc; h4 { color: @color }'
fs.writeFileSync(path.join(templateDir, templateName, 'html.jade'), html)
fs.writeFileSync(path.join(templateDir, templateName, 'style.less'), css)

Expand Down Expand Up @@ -255,6 +295,20 @@ describe('Email templates', function () {
})
})

it('on missing html, text, and subject file', function (done) {
emailTemplates(templateDir, function (err, template) {
expect(err).to.be.null
template(templateName, {item: 'test'}, function (err, html, text, subject) {
expect(err.code).to.equal('ENOENT')
expect(html).to.be.undefined
expect(text).to.be.undefined
expect(subject).to.be.undefined

done()
})
})
})

it('on empty html and text file', function (done) {
fs.writeFileSync(path.join(templateDir, templateName, 'html.ejs'), '')
fs.writeFileSync(path.join(templateDir, templateName, 'text.ejs'), '')
Expand All @@ -269,5 +323,22 @@ describe('Email templates', function () {
})
})
})

it('on empty html, text, and subject file', function (done) {
fs.writeFileSync(path.join(templateDir, templateName, 'html.ejs'), '')
fs.writeFileSync(path.join(templateDir, templateName, 'text.ejs'), '')
fs.writeFileSync(path.join(templateDir, templateName, 'subject.ejs'), '')

emailTemplates(templateDir, function (err, template) {
expect(err).to.be.null
template(templateName, {item: 'test'}, function (err, html, text, subject) {
expect(html).to.be.undefined
expect(text).to.be.undefined
expect(subject).to.be.undefined
expect(err.message).to.contain('both empty in path')
done()
})
})
})
})
})
2 changes: 1 addition & 1 deletion test/testTemplateManager.js
Expand Up @@ -152,7 +152,7 @@ describe('Template manager', function () {

// Write out some test LESS files.
fs.writeFileSync(testMainLessFile, '@import "includes.less";')
fs.writeFileSync(testIncludesFile, '.body { color: #333}')
fs.writeFileSync(testIncludesFile, '.body { color: #333333}')

var file = {
filename: testMainLessFile,
Expand Down

0 comments on commit cb7b030

Please sign in to comment.