I am using https://github.com/crocodilejs/node-email-templates
Which is rather good to send emails from a node.js backend
because :
I have been trying to integrate it with mjml but I do not know if it is feasible.
To date my workflow is :
I do not know how the inline styling succeed in node-email-template, but as the element name does not match as the final html is without any mjml component name.
I suppose it will fail doing its inlining jov.
So I do not see a workflow combining mjml and node-email-template
https://github.com/crocodilejs/node-email-templates
Currently the best seem to use a email template from theme forest or other open source separating content from structure thanks to jade.
But MJML though interesting does not seem to bring much.
Hi @sinsunsan
I don't know much about node-email-templates but it looks like a "full stack" css/sass/less + templating + "sugar" html syntax framework to build emails. Looks like you can add MJML into the template manager[1], but I guess you'll have to build your own workflow.
I think you misunderstood what's the purpose of MJML :
(this passing variable is not clear in your doc by the way)
MJML is NOT a _templating_ language, it's only a markup language. If you need to handle variables, you'll have to use something like handlebars before/after rendering the MJML. Note that conditionnals structure should be applied __before__ transpiling MJML into HTML, because MJML has internal logic to compute how much column you have in a section to define width and many other things.
MJML is like an HTML document but you can't put MJML inside an HTML document, the flow should be : Templating + Pug should produce MJML and MJML will produce your final HTML.
MJML is already taking care of inlining your style when using mj-style so you don't need to take care of that.
I hope i'd answered your concerns
[1] : https://github.com/crocodilejs/node-email-templates/blob/master/src/template-manager.js
Ok thanks for your response.
If I were to compile it statically (from command line) with gulp pug + gulp mjml it is ok. I started from a demo project in github
https://github.com/herrkessler/jade-mjml
It works.
But the problem is that I do not compile statically but dynamically when my node server ask to send a email with specific variables, the name of the user I send, ...
So node-email-templates is in charge of compiling the email html from :
So I really do not know when to run the mjml > html compilation.
Per aps at this end ? When node-email-templates is about to send the email, I could convert mjml tags to html tags ?
Does the file need to have only mjml tags ? Or could have other normal html tags ?
Do you have a prefered workflow to integrate to a node.js express server ?
Here is my file that actually send the email
May be I can use the mjml lib where I writed
debug(renderedTemplate.html);
With the complete html (that would in this case contain mjml tags.
And before sending.
'use strict';
const config = require('../../config')();
const debug = require('debug')('emails-send');
const nodemailer = require('nodemailer');
const mailGunTransport = require('nodemailer-mailgun-transport');
const path = require('path');
const templateDir = path.resolve(__dirname, '..', '..', '..', 'templates', 'emails');
const EmailTemplate = require('email-templates').EmailTemplate;
//https://github.com/orliesaurus/nodemailer-mailgun-transport
const transport = nodemailer.createTransport(mailGunTransport(config.emails.mailgun.auth));
// Global email settings
const emailSettings = config.emails.from;
/**
* Send the email trough mailgun api
*
* @param {object} email : email object
* email.to destination email
* email.subject email subject
* @param {string} templateId : identifier of the template to use
* @param {object} templateVars : Object of variables to send to the template
*/
exports.sendEmail = function (email, templateId, templateVars) {
return new Promise(function (resolve, reject) {
var template = new EmailTemplate(path.join(templateDir, templateId));
template.render(templateVars, function(err, renderedTemplate) {
if (err) {
debug('there was an error rendering the template.');
return console.error(err)
}
debug(renderedTemplate.html);
transport.sendMail({
// mandrillOptions: {
// template_name: templateId,
// },
from: emailSettings.from,
to: email.to,
subject: email.subject,
bcc: emailSettings.bcc,
html: renderedTemplate.html,
text: renderedTemplate.text
}, function(err, info) {
if (err) {
debug(err);
reject(err);
}
else {
debug(info);
resolve(info);
}
});
});
});
};
Ok it works
I passed my html resulting for pug compilation
in
const mjml = require('mjml');
template.render(templateVars, function(err, renderedTemplate) {
if (err) {
debug('there was an error rendering the template.');
return console.error(err)
}
debug(renderedTemplate.html);
renderedTemplate.html is looking like that
<mjml><mj-body><mj-section><mj-column width="100%"><mj-image width="100" src="http://res.cloudinary.com/hrscywv4p/image/upload/c_limit,h_1440,w_720,f_auto,q_90/v1/206926/LOGO_BAM_knz1yz.png"></mj-image><mj-divider border-color="#F45E43"></mj-divider><mj-text font-size="20px" color="#F45E43" font-family="helvetica">Bam Architecture</mj-text></mj-column></mj-section><mj-section><mj-text font-size="20px" color="#F45E43" font-family="helvetica"></mj-text></mj-section><div>Hello Sebastien Lucas</div><div>BAM vous propose une offre !</div><div>Dites-nous sous 24 heures si vous participer.</div><div class="call-action"><span>Voir le</span><a href="http://dev.bam.archi/offer/22?archiSelect">d茅tail de l'offre</a></div></mj-body></mjml>
then passed it to mjml.mjml2html function
let mjmlRendered = mjml.mjml2html(renderedTemplate.html);
and get like this
{ errors: [],
html: '<!doctype html>\n<html xmlns="http://www.w3.org/1999/xhtml" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office">\n<head>\n <title></title>\n <!--[if !mso]><!-- -->\n <meta http-equiv="X-UA-Compatible" content="IE=edge">\n <!--<![endif]-->\n<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">\n<style type="text/css">\n #outlook a { padding: 0; }\n .ReadMsgBody { width: 100%; }\n .ExternalClass { width: 100%; }\n .ExternalClass * { line-height:100%; }\n body { margin: 0; padding: 0; -webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%; }\n table, td { border-collapse:collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; }\n img { border: 0; height: auto; line-height: 100%; outline: none; text-decoration: none; -ms-interpolation-mode: bicubic; }\n p { display: block; margin: 13px 0; }\n</style>\n<!--[if !mso]><!-->\n<style type="text/css">\n @media only screen and (max-width:480px) {\n @-ms-viewport { width:320px; }\n @viewport { width:320px; }\n }\n</style>\n<!--<![endif]-->\n<!--[if mso]>\n<xml>\n <o:OfficeDocumentSettings>\n <o:AllowPNG/>\n <o:PixelsPerInch>96</o:PixelsPerInch>\n </o:OfficeDocumentSettings>\n</xml>\n<![endif]-->\n<!--[if lte mso 11]>\n<style type="text/css">\n .outlook-group-fix {\n width:100% !important;\n }\n</style>\n<![endif]-->\n<style type="text/css">\n @media only screen and (min-width:480px) {\n .mj-column-per-100 { width:100%!important; }\n }\n</style>\n</head>\n<body>\n <div style="margin:0px auto;"><table role="presentation" cellpadding="0" cellspacing="0" style="font-size:0px;width:100%;" align="center" border="0"><tbody><tr><td style="text-align:center;vertical-align:top;direction:ltr;font-size:0px;padding:20px 0px;"><!--[if mso | IE]>\n <table role="presentation" border="0" cellpadding="0" cellspacing="0"><tr><td style="vertical-align:top;width:NaNpx;">\n <![endif]--><div class="mj-column-per-100 outlook-group-fix" style="vertical-align:top;display:inline-block;direction:ltr;font-size:13px;text-align:left;width:100%;"><table role="presentation" cellpadding="0" cellspacing="0" width="100%" border="0"><tbody><tr><td style="word-break:break-word;font-size:0px;padding:10px 25px;" align="center"><table role="presentation" cellpadding="0" cellspacing="0" style="border-collapse:collapse;border-spacing:0px;" align="center" border="0"><tbody><tr><td style="width:50px;"><img alt="" title="" height="auto" src="http://res.cloudinary.com/hrscywv4p/image/upload/c_limit,h_1440,w_720,f_auto,q_90/v1/206926/LOGO_BAM_knz1yz.png" style="border:none;border-radius:;display:block;outline:none;text-decoration:none;width:100%;height:auto;" width="50"></td></tr></tbody></table></td></tr><tr><td style="word-break:break-word;font-size:0px;padding:10px 25px;"><p style="font-size:1px;margin:0px auto;border-top:4px solid #F45E43;width:100%;"></p><!--[if mso | IE]><table role="presentation" align="center" border="0" cellpadding="0" cellspacing="0" style="font-size:1px;margin:0px auto;border-top:4px solid #F45E43;width:100%;" width="100"><tr><td style="height:0;line-height:0;">聽</td></tr></table><![endif]--></td></tr><tr><td style="word-break:break-word;font-size:0px;padding:10px 25px;" align="left"><div class="" style="cursor:auto;color:#F45E43;font-family:helvetica;font-size:20px;line-height:22px;text-align:left;">Bam Architecture</div></td></tr></tbody></table></div><!--[if mso | IE]>\n </td></tr></table>\n <![endif]--></td></tr></tbody></table></div>\n</body>\n</html>' }
and I coud pass to node mailer the final version
transport.sendMail({
from: emailSettings.from,
to: email.to,
subject: email.subject,
bcc: emailSettings.bcc,
html: mjmlRendered.html,
text: renderedTemplate.text
}
Most helpful comment
Ok it works
I passed my html resulting for pug compilation
in
renderedTemplate.html is looking like that
then passed it to mjml.mjml2html function
and get like this
and I coud pass to node mailer the final version