mjmlio / mjml

MJML: the only framework that makes responsive-email easy
https://mjml.io
MIT License
16.93k stars 953 forks source link

Add the ability to merge mj-includes, but not render to html #2465

Closed F21 closed 2 years ago

F21 commented 2 years ago

Is your feature request related to a problem? Please describe. During development, I want to have modularity for the files I am working on, so mj-include solves the problem. In production, the mjml files will be passed through the templating system first, because depending on the conditionals within the template, the number of columns might change, which will result in the html being rendered to be different. The mjml will then be passed to a mjml rendering server, which will return the rendered html.

Describe the solution you'd like I would like to be able to "flatten" all my mjml files when deploying for production, but not render to html, perhaps via a configuration option in the mjml cli. The reason for this is that the mjml has to pass through the template engine first. In addition, I want the mjml rendering server to be stateless for ease of deployment (everything else is written in Go). The rendering process in production would look like:

Describe alternatives you've considered None.

Additional context None.

iRyusa commented 2 years ago

I think if you do it with a node script you'll be able to do it easily

import mjml2html from 'mjml' // load default component
import components from 'mjml-core/lib/components.js'
import Parser from 'mjml-parser-xml'
import jsonToXML from 'mjml-core/lib/helpers/jsonToXML.js'

const xml = `
<mjml>
  <mj-body>
    <mj-section>
      <mj-column>

        <mj-image width="100px" src="/assets/img/logo-small.png"></mj-image>

        <mj-divider border-color="#F45E43"></mj-divider>

        <mj-text font-size="20px" color="#F45E43" font-family="helvetica">Hello World</mj-text>

      </mj-column>
    </mj-section>
  </mj-body>
</mjml>
`

const mjml = Parser(xml, {
      components,
      filePath: '.',
      actualPath: '.'
    })

console.log(JSON.stringify(mjml))
console.log(jsonToXML(mjml))
iRyusa commented 2 years ago

If anyone willing to make this snippet as a cli feature feel free to open a PR, i'm closing for now

coclav commented 1 year ago

Hi @iRyusa we are willing to give it serious thoughts, but could you explain how that would work with mj-include ?

I'd like to have a 100% CLI way to include files. With the way you describe above, where would i pass the content of what needs to be "included" ?

I want to work on an API that looks like that flatten(xml, includes)

const includes = { 
head: `
  <mj-head>
    <mj-attributes>
      <mj-all font-family="Helvetica" />
      <mj-text font-size="18px" line-height="30px" color="#404148" />
      <mj-button font-size="18px" line-height="25px" background-color="#ef7d00" color="white" />
      <mj-class name="title" font-weight="600" />
      <mj-class name="smaller" font-size="15px" />
      <mj-class name="divider" border-width="2px" border-color="#008b8b" />
    </mj-attributes>
  </mj-head>
`}

const xml = `
<mjml>
  <mj-body>
    <mj-include path="head.mjml" />
    <mj-section>
      <mj-column>

        <mj-image width="100px" src="/assets/img/logo-small.png"></mj-image>

        <mj-divider border-color="#F45E43"></mj-divider>

        <mj-text font-size="20px" color="#F45E43" font-family="helvetica">Hello World</mj-text>

      </mj-column>
    </mj-section>
  </mj-body>
</mjml>
iRyusa commented 1 year ago

Include just work with filesystems there's no way for now to get the API you're aiming for.

The script described here : https://github.com/mjmlio/mjml/issues/2465#issuecomment-1109515536 just allow you to resolve mj-include in a input and output either the JSON version of resolved MJML or the XML version of resolved MJML