handlebars-mjml-generator.ts 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
  1. import dateFormat from 'dateformat';
  2. import fs from 'fs-extra';
  3. import Handlebars from 'handlebars';
  4. import mjml2html from 'mjml';
  5. import path from 'path';
  6. import { EmailGenerator, EmailPluginDevModeOptions, EmailPluginOptions } from './types';
  7. /**
  8. * Uses Handlebars (https://handlebarsjs.com/) to output MJML (https://mjml.io) which is then
  9. * compiled down to responsive email HTML.
  10. */
  11. export class HandlebarsMjmlGenerator implements EmailGenerator {
  12. onInit(options: EmailPluginOptions | EmailPluginDevModeOptions) {
  13. const partialsPath = path.join(options.templatePath, 'partials');
  14. this.registerPartials(partialsPath);
  15. this.registerHelpers();
  16. }
  17. generate(
  18. subject: string,
  19. template: string,
  20. templateVars: any,
  21. ) {
  22. const compiledSubject = Handlebars.compile(subject);
  23. const compiledTemplate = Handlebars.compile(template);
  24. const subjectResult = compiledSubject(templateVars);
  25. const mjml = compiledTemplate(templateVars);
  26. const body = mjml2html(mjml).html;
  27. return { subject: subjectResult, body };
  28. }
  29. private registerPartials(partialsPath: string) {
  30. const partialsFiles = fs.readdirSync(partialsPath);
  31. for (const partialFile of partialsFiles) {
  32. const partialContent = fs.readFileSync(path.join(partialsPath, partialFile), 'utf-8');
  33. Handlebars.registerPartial(path.basename(partialFile, '.hbs'), partialContent);
  34. }
  35. }
  36. private registerHelpers() {
  37. Handlebars.registerHelper('formatDate', (date: Date, format: string | object) => {
  38. if (typeof format !== 'string') {
  39. format = 'default';
  40. }
  41. return dateFormat(date, format);
  42. });
  43. Handlebars.registerHelper('formatMoney', (amount: number) => {
  44. return (amount / 100).toFixed(2);
  45. });
  46. }
  47. }