Looking for good technique for managing email templates

tl;dr I want to manage all email templates with a single file and would like to build them in an easy to read format (to be parsed later). Also, I don’t know what I’m doing. :sweat_smile:

Like many apps, I generate emails after specific actions are taken like when a new record is created, modified, or deleted. Of course, this calls for a template of some kind.

I’m new to Meteor, and JavaScript in general, and the lack of heredoc support in JavaScript has left me to do the best I could to handle this situation. I’m looking for some advice on improving what I’m doing because it’s not great. :blush:

I don’t want to clutter the app with the email templates. I want to be able to view and manage all the templates from the same file. Ideally I’d be able to write the templates in Markdown.

I have a Meteor method called sendEmail (copied from the Meteor docs) that takes an object which contains all the data the method needs to send an email. e.g. The name of the “template” to be used and the data for the template.

  , sendEmail: function (event, options) {

    // ... broken check()s ...

    var messageBody = '';
    switch(options.emailType) {
      case 'eventAdd':
        messageBody  = '<h1>ETO Event Added</h1>';
        messageBody += '<ul>';
        messageBody += '<li>Start: ' + event.etoStart + '</li>';
        messageBody += '<li>Stop: ' + event.etoStop + '</li>';
        messageBody += '<li>Description: ' + event.description + '</li>';
        messageBody += '<li>Submitted: ' + event.etoeventSubmitted + '</li>';
        messageBody += '</ul>';
        break;
      case 'eventUpdate':
        messageBody  = '<h1>ETO Event Updated</h1>';
        messageBody += '<ul>';
        messageBody += '<li>Start: ' + event.etoStart + '</li>';
        messageBody += '<li>Stop: ' + event.etoStop + '</li>';
        messageBody += '<li>Description: ' + event.description + '</li>';
        messageBody += '<li>Submitted: ' + event.etoeventSubmitted + '</li>';
        messageBody += '</ul>';
        break;
      case 'eventDelete':
        break;
      case 'userAdd':
        break;
      case 'userUpdate':
        break;
      case 'userDisable':
        break;
      case 'userDelete':
        break;
      default:
        return 'no email template specified'
    }

    // Let other method calls from the same client start running,
    // without waiting for the email sending to complete.
    this.unblock();
    
    Email.send({
      to:        options.to
      , from:    process.env.MAIL_USERNAME
      , subject: options.subject
      , html:    options.body
    });
  }

It’s used like this:

var event = {
  description: $(e.target).find('[name=description]').val()
  , etoStart:  etoStart.format()
  , etoStop:   etoStop.format()
};

// ... update record ...

// email to employee
var options = {
  'emailType': 'eventUpdate'
  , 'to':      Meteor.user().emails[0].address
  , 'subject': 'ETO Event Updated'
  //, 'cc': ''
};
Meteor.call('sendEmail', event, options);

My flow for email templates at the moment is the following, it was a mess before, now it’s nice and simple:

Using Arunoda’s server-side rendering package (meteorhacks:ssr) I put my email templates as full html, including helpers {{ }}, in the /private folder. This allows you to get the content of these files through Assets.getText().

You compile those emails server-side, like this:

SSR.compileTemplate("someEmailName", Assets.getText("emailTemplates/someEmail.html"));

Then you render the email, passing in the data to be used inside the email template:

var html = SSR.render("someEmailName", {data1: data1, data2: data2});

After that it’s just a matter of passing that html var as the html parameter in the Email.send() function.

It’s working great, we’re using mandrill to send mails and never had any issues.

7 Likes

I’m just getting to implementing this but it works perfectly. Exactly what I was looking for and dead simple. :smiley:

That is a great suggestion, thanks!

I haven’t gotten to the point where I need email templates, but this sounds like a winner.

I use @cmather’s server side handlebars package - it’s really neat and straightforward: