Closed igalarzab closed 7 years ago
Hi @igalarzab
Well, I understand the concept behind it, but component are more than an html node in the body. They are interact with their children, can add some code into the head, ...
The real bottleneck in MJML isn't rendering the template, it's the time to boot up everything. Even if you're splitting your template into partials, you still need to compile MJML to an HTML with your Jinja stuff and the time will remain the same.
With MJML4, mj-raw now behave like it should (#600) so HTML produced with your Jina templating should be "ready to use". I think it allows you to compile the MJML only one time instead of everytime you need to send an email, so it's no longer an issue ?
I see... I suspected that compiling partials was not gonna be easy 😅
Probably using mj-raw
will work. I'm closing this ticket, thanks @iRyusa :)
Thanks I have same problem here and it works with mj-raw, it's cool.
I have the same problem. We have personalized emails for each user, (a very personalized list of news) and we don't want to introduce a dependency in production of mjml
. It has sense to pre-build the template, and commit them to our repo. I don't see the benefit of mjml in production.
Then production just does the interpolation on the compiled-by-mjml-html (we are using lodash _.template for this), and send the email.
It would be nice to have a partial, so each of the news item has its own HTML partial. (and build a list of those news with a loop)
We will do this manually. Develop the entire HTML email with a mjml mock template that contains 5 fake news. Then copy paste manually the news-item HTML partial into its own file.
Well, what you're asking for is a template language on top of MJML. You can just use something like Handlebars / Mustache / pug / ... and loop over your data instead of the "limited" lodash implem.
Partial "exist" in form of mj-include, but won't be able to render on its own as most of markup can add head
styles like media queries.
<mj-raw>{{#each people}}</mj-raw>
<mj-include path="./news-block.mjml" />
</mj-raw>{{/each}}</mj-raw>
This is totally valid, and would just behave as you want in MJML4. I don't get why you would need to edit manually the html here, and you might just miss some optimization & some important head style here.
we don't want to introduce a dependency in production of mjml
Which is fine, but you add some complexity by not using it. The easy way is to pipe a templating language to the mjml2html
function, if you want to do the process the other way, just use the solution below.
@iRyusa I see, thanks for the tip and quick reply!. I see, the benefit of looping with more complex templating language, and partials with mj-include
. That's great DX. And your recommendation is to do something like this (as an example) https://stackoverflow.com/questions/43111628/mjml-template-interpolation-dynamic-data-context/43112307
I can see this is great workflow and it seems to work for many people, because I don't see anyone complaining about performance, etc.
But in our case, only 1 simple email template with a list of news, that needs to be very performant (50K emails per day), I'm concerned (maybe irrationally) about the performance. We would leave mjml for development -> export HTML. And then adapt that HTML to limited but performant lodash templates that we can interpolate fast with _.template
.
The HTML is not changing, only the content (the news in the newsletter). I'm not loading conditionally different mj-components
. So the head styles, etc are constant.
Or maybe MJML has a very optimized way of doing this internally?
Or maybe in the future MJML could expose this compilation step on load time, with some mechanism like lodash _.template
offers. First, compile the template (only once), then, use directly the compiled template (thousand of times, once per email sent). See the example of usage:
https://lodash.com/docs/4.17.11#template
Thanks again for maintaining mjml through the years. We are falling in love with the documentation, app, VS Code extension, etc. It's just this small issue that concerns me. Sorry if my comments looks rant'ish. Not the case ❤️
Well for me implementing this inside MJML won't offer any perf benefit since the work will be the same if done by MJML core or by an external dependencies.
You can do something in between that pre-compile the MJML with templating "loops" like let's say how many news you'd want into the email, and just keep the string interpolation as it's done now. It won't add much and should be flexible enough for you. This would be done only one time, instead of each time you're sending the mail ?
About the optimization, I don't know you might miss some of outlook comment merging that MJML does at the end, most likely style inside mj-style inline="inline"
won't be applied, and maybe the code won't be perfectly minified as you altered the final HTML output ?
Always a pleasure to have some positive feedback ❤️Thanks ! 👍
Feel free to come on Slack to discuss about this, we might find a better workflow for you !
Hi there!
I was wondering if there is any possibility of rendering parts of a template, without generating the full document structure. I can see in #459 a similar issue.
Our use case is very similar to the one expressed on that issue. We have a template engine that is interpolating some variables (and blocks), and after that, we generate the HTML using mjml ( Jinja -> MJML -> HTML).
Currently, we are facing a performance problem in mjml, as it's our current bottle-neck in the process (calling a JS script from another language isn't very performant). Ideally we would like to cache the templates, but currently is impossible as when the process reaches the mjml phase, the template already has all the variables interpolated, and the template is not generic anymore (it's for an specific user).
So we would like to inverse the process to (mjml -> jinja -> html), but to do that we need to be able to run the mjml engine in partials, as we have the mjml templates split into different partials that are rendered using Jinja.
Is it possible to do something like this? I'm happy to work on it if it's not possible yet (and the design of the project allows it)