Skip to content

Commit

Permalink
Merge pull request forwardemail#172 from albertosouza/master
Browse files Browse the repository at this point in the history
Add suport to sub folders for localization
  • Loading branch information
niftylettuce authored Jul 25, 2016
2 parents db2c9aa + 65fcf5b commit e7ede03
Show file tree
Hide file tree
Showing 18 changed files with 313 additions and 34 deletions.
50 changes: 50 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,55 @@ Promise.all(templates)
})
```
#### Localized template
Localized template folder:
```
templates/
templates/newsletter/
// defalt locale templates are stored in root folder and by default is en-us:
templates/newsletter/html.{{ext}}
templates/newsletter/style.{{ext}}
// for add pt-br locale:
templates/newsletter/pt-br/html.{{ext}}
templates/newsletter/pt-br/style.{{ext}}
```
To render the pt-br localized version for folder structure above, pass locale name in `.render` method
```javascript
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, result) {
// result.html
// result.text
})
var async = require('async')
var users = [
{name: 'John', pasta: 'Rigatoni'},
{name: 'Luca', pasta: 'Tortellini'}
]
async.each(users, function (user, next) {
// render the pt-br localized template:
newsletter.render(user, 'pt-br' function (err, result) {
if (err) return next(err)
// result.html
// result.text
// result.subject
})
}, function (err) {
//
})
```
### More
Please check the [examples directory](https://github.com/niftylettuce/node-email-templates/tree/master/examples)
Expand All @@ -246,6 +295,7 @@ Please check the [examples directory](https://github.com/niftylettuce/node-email
* Jason Sims <[email protected]>
* Miguel Mota <[email protected]>
* Jeduan Cornejo <[email protected]>
* Alberto Souza <[email protected]>
> Full list of contributors can be found on the [GitHub Contributor Graph][gh-graph]
Expand Down
30 changes: 30 additions & 0 deletions examples/handlebars_i18n/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
var path = require('path')
var EmailTemplate = require('../..').EmailTemplate
var _ = require('lodash')
var Handlebars = require('handlebars')

var templateDir = path.resolve(__dirname, '..', 'templates', 'newsletter-hbs-i18n')

Handlebars.registerHelper('capitalize', function capitalize (context) {
return context.toUpperCase()
})

Handlebars.registerPartial('name',
'{{ capitalize name.first }} {{ capitalize name.last }}'
)

var template = new EmailTemplate(templateDir)
var locals = {
email: '[email protected]',
name: {first: 'Mamma', last: 'Mia'}
}

template.render(locals, 'pt-br')
.then(function (results) {
console.log('In pt-br:\n', results)
})

template.render(locals)
.then(function (results) {
console.log('In default en-us:\n', results)
})
1 change: 1 addition & 0 deletions examples/templates/newsletter-hbs-i18n/html.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<h1>Hi there {{> name}}</h1>
1 change: 1 addition & 0 deletions examples/templates/newsletter-hbs-i18n/pt-br/html.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<h1>Oi {{> name}} in pt-br!</h1>
10 changes: 10 additions & 0 deletions examples/templates/newsletter-hbs-i18n/pt-br/style.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
@import '../../common';

body {
background-color: #ddd;
color: white;
}

h1 {
text-align: center;
}
1 change: 1 addition & 0 deletions examples/templates/newsletter-hbs-i18n/pt-br/text.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Oi {{> name}} in pt-br!.
10 changes: 10 additions & 0 deletions examples/templates/newsletter-hbs-i18n/style.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
@import '../common';

body {
background-color: #ddd;
color: white;
}

h1 {
text-align: center;
}
1 change: 1 addition & 0 deletions examples/templates/newsletter-hbs-i18n/text.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Hi there {{> name}}
1 change: 1 addition & 0 deletions examples/templates/newsletter-i18n/html.ejs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<h1>Hi there <%= name.first %> <%= name.last %></h1>
1 change: 1 addition & 0 deletions examples/templates/newsletter-i18n/pt-br/html.ejs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<h1>Oi <%= name.first %> <%= name.last %></h1>
10 changes: 10 additions & 0 deletions examples/templates/newsletter-i18n/pt-br/style.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
@import '../common';

body {
background-color: #ddd;
color: white;
}

h1 {
text-align: center;
}
1 change: 1 addition & 0 deletions examples/templates/newsletter-i18n/pt-br/text.ejs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Oi <%= name.first %> <%= name.last %>.
10 changes: 10 additions & 0 deletions examples/templates/newsletter-i18n/style.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
@import '../common';

body {
background-color: #ddd;
color: white;
}

h1 {
text-align: center;
}
1 change: 1 addition & 0 deletions examples/templates/newsletter-i18n/text.ejs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Hi there <%= name.first %> <%= name.last %>.
5 changes: 5 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@
{
"name": "Jeduan Cornejo",
"email": "[email protected]"
},
{
"name": "Alberto Souza",
"email": "[email protected]"
}
],
"keywords": [
Expand All @@ -38,6 +42,7 @@
"email-templates",
"juice",
"inline",
"i18n",
"css"
],
"homepage": "https://github.com/niftylettuce/node-email-templates",
Expand Down
99 changes: 65 additions & 34 deletions src/email-template.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,34 +4,41 @@ import {basename} from 'path'
import juice from 'juice'
import isFunction from 'lodash/isFunction'
import assign from 'lodash/assign'
import {ensureDirectory, readContents, renderFile} from './util'
import {resolveTPLFolder, readContents, renderFile} from './util'

const debug = Debug('email-templates:email-template')

export default class EmailTemplate {
constructor (path, options = {}) {
this.files = {}
this.path = path
this.dirname = basename(path)
this.options = options
debug('Creating Email template for path %s', basename(path))
// localized templates cache
this.ltpls = {}
}

_init () {
if (this.isInited) return P.resolve()
_init (locale) {
if (!locale) locale = 'en-us'

if (!this.ltpls[locale]) this.ltpls[locale] = { files: {} }

if (this.ltpls[locale].isInited) {
return P.resolve() // i18n cache
}

debug('Initializing templates')
return ensureDirectory(this.path)
.then(() => this._loadTemplates())
return resolveTPLFolder(this.path, locale)
.then((p) => this._loadTemplates(p, locale))
.then(() => {
this.isInited = true
this.ltpls[locale].isInited = true
debug('Finished initializing templates')
})
}

_loadTemplates () {
_loadTemplates (p, locale) {
return P.map(['html', 'text', 'style', 'subject'], (type) => {
return readContents(this.path, type)
return readContents(p, type)
})
.then((files) => {
let [html, text, style, subject] = files
Expand All @@ -45,56 +52,71 @@ export default class EmailTemplate {
if (html) {
debug('Found HTML file %s in %s', basename(html.filename), this.dirname)
}
this.files.html = html
this.ltpls[locale].files.html = html

if (text) {
debug('Found text %s file in %s', basename(text.filename), this.dirname)
}
this.files.text = text
this.ltpls[locale].files.text = text

if (style) {
debug('Found stylesheet %s in %s', basename(style.filename), this.dirname)
}
this.files.style = style
this.ltpls[locale].files.style = style

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

debug('Finished loading template')
})
}

renderText (locals, callback) {
renderText (locals, locale, callback) {
if (!locale || (!callback && isFunction(locale))) {
callback = locale
locale = 'en-us'
}

debug('Rendering text')
return this._init()
return this._init(locale)
.then(() => {
if (!this.files.text) return null
return renderFile(this.files.text, locals)
if (!this.ltpls[locale].files.text) return null
return renderFile(this.ltpls[locale].files.text, locals)
})
.tap(() => debug('Finished rendering text'))
.nodeify(callback)
}

renderSubject (locals, callback) {
renderSubject (locals, locale, callback) {
if (!locale || (!callback && isFunction(locale))) {
callback = locale // locale is optional
locale = 'en-us'
}

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

renderHtml (locals, callback) {
renderHtml (locals, locale, callback) {
if (!locale || (!callback && isFunction(locale))) {
callback = locale // locale is optional
locale = 'en-us'
}

debug('Rendering HTML')
return this._init()
return this._init(locale)
.then(() => {
return P.all([
renderFile(this.files.html, locals),
this._renderStyle(locals)
renderFile(this.ltpls[locale].files.html, locals),
this._renderStyle(locals, locale)
])
})
.then((results) => {
Expand All @@ -110,19 +132,25 @@ export default class EmailTemplate {
.nodeify(callback)
}

render (locals, callback) {
render (locals, locale, callback) {
if (isFunction(locals)) {
callback = locals
locals = {}
} else if (locals) {
locals = assign({}, locals)
}

if (!callback && isFunction(locale)) {
callback = locale // locale is optional
locale = 'en-us'
}

debug('Rendering template with locals %j', locals)

return P.all([
this.renderHtml(locals),
this.renderText(locals),
this.renderSubject(locals)
this.renderHtml(locals, locale),
this.renderText(locals, locale),
this.renderSubject(locals, locale)
])
.then((rendered) => {
let [html, text, subject] = rendered
Expand All @@ -133,22 +161,25 @@ export default class EmailTemplate {
.nodeify(callback)
}

_renderStyle (locals) {
_renderStyle (locals, locale) {
return new P((resolve) => {
// cached
if (this.style !== undefined) return resolve(this.style)
if (this.ltpls[locale].style !== undefined) {
return resolve(this.ltpls[locale].style)
}

// no style
if (!this.files.style) return resolve(null)
if (!this.ltpls[locale].files.style) return resolve(null)

if (this.options.sassOptions) {
locals = assign({}, locals, this.options.sassOptions)
}

debug('Rendering stylesheet')
resolve(renderFile(this.files.style, locals)

resolve(renderFile(this.ltpls[locale].files.style, locals)
.then((style) => {
this.style = style
this.ltpls[locale].style = style
debug('Finished rendering stylesheet')
return style
}))
Expand Down
Loading

0 comments on commit e7ede03

Please sign in to comment.