forwardemail / email-templates

Create, preview (browser/iOS Simulator), and send custom email templates for Node.js. Made for @forwardemail, @ladjs, @cabinjs, @spamscanner, and @breejs.
https://forwardemail.net/docs/send-emails-with-node-js-javascript
MIT License
3.66k stars 339 forks source link

dust partials require double configuration because consolidate #373

Closed morungos closed 5 years ago

morungos commented 5 years ago

This is related to #88, but it deserves better documentation and I have a modestly different solution.

The problem is: out of the box, dustjs partials don't work that well, because the file references are resolved using a different system to the initial templates. The views directory can be passed to the main new Email(), but templates fail to render with messages like:

{ Error: ENOENT: no such file or directory, open './shared/html.dust'
  cause: 
   { Error: ENOENT: no such file or directory, open './shared/html.dust'
     errno: -2,
     code: 'ENOENT',
     syscall: 'open',
     path: './shared/html.dust' },
  isOperational: true,
  errno: -2,
  code: 'ENOENT',
  syscall: 'open',
  path: './shared/html.dust' }

For reference, my template reads:

{>"shared/html"/}

{<bodyContent}
...
{/bodyContent}
{<signature}
...
{/signature}

The issue can be replicated by the simple script:

const Email = require('email-templates');

const email = new Email({
  message: {
    from: 'stuart@morungos.com'
  },
  // uncomment below to send emails in development/test env:
  // send: true
  transport: {
    jsonTransport: true
  },
  juice: true,
  juiceResources: {
    applyAttributesTableElements: false
  },
  views: {
    root: "/Users/stuart/git/api-server/packages/user-service/templates",
    options: {
      extension: 'dust'
    }
  }
});

email
  .send({
    template: 'feedback',
    message: {
      to: 'elon@spacex.com'
    },
    locals: {
      name: 'Elon'
    }
  })
  .then(console.log)
  .catch((error) => {
    console.error(error);
  });

When run, even with a shared/html.dust file in place, we get the error above.

It's easy to resolve by modifying the locals to:

    locals: {
      name: 'Elon',
      views: "/Users/stuart/git/api-server/packages/user-service/templates"
    }

In other words, passing the views root into the render for consolidate, as well as into the initial configuration, works fine. However, it would be nicer if we didn't to do that, or that it would be documented.

This seems to only be necessary in practice for dustjs, so I don't know whether a new config item for that might be better.

niftylettuce commented 5 years ago

PR welcome or documentation fix to README is welcome