GrapesJS / mjml

Newsletter Builder with MJML components in GrapesJS
http://grapesjs.com/demo-mjml.html
BSD 3-Clause "New" or "Revised" License
624 stars 222 forks source link

Template export adds a html body tag in mjml code #285

Closed Frankosntin closed 1 year ago

Frankosntin commented 2 years ago

Hi, im a newbie coder and im using Grapesjs in a react component. i am having troubles to export mjml and html code. When i click on export template button it add an extra tag before and after mjml code. It seems to be the canvas wrapper. how can i prevent this issue?

my console log display this error: index.js:1 Uncaught Error: Malformed MJML. Check that your structure is correct and enclosed in <mjml> tags.

thats my code:

`import React, {useState, useEffect} from 'react'; import * as grapesjs from 'grapesjs';

import grapesJSMJML from 'grapesjs-mjml'

import {useParams} from 'react-router-dom' import { API_HOST } from './api_utils';

const Editor = () => { const [editor, setEditor] = useState(null); const pageId = useParams(); console.log('params editor :>>', pageId )

useEffect(() => {
  const editor =grapesjs.init({
    id:"#editor",
    noticeOnUnload: 0,
    container:"#editor",
    avoidInlineStyle : false,
    fromElement: true,
    storageManager:{
      type: "remote",
      stepsBeforeSave: 1,
      contentTypeJson:true,
      storeComponents:true,
      storeStyles:true,
      storeHtml:true,
      storeCss: true,
      headers: {
        "Content-Type": "application/json",
      },
      id: "mycustom-",
      urlStore: `${API_HOST}/${pageId.pageId}/content`,
      urlLoad: `${API_HOST}/${pageId.pageId}/content`,
    },
    plugins: [grapesJSMJML],
    pluginsOpts:{
      grapesJSMJML:{
        resetDevices: false,
        overwriteExport: true,
        resetStyleManager:true,
        resetBlocks:true,

      },
    }
  });

  editor.DomComponents.clear()
  editor.addComponents('<mjml><mj-body><mj-section></mj-section></mj-body></mjml>')
  setEditor(editor);
}, []);

return (

) } export default Editor `

and that is the export template modal: image

zietbukuel commented 2 years ago

This issue also happens to me. Check out this fiddle.

https://jsfiddle.net/zietbukuel/m1vcjgn5/2/

Frankosntin commented 2 years ago

@zietbukuel I cant solve that yet, but i found another open soucer drag-and-drop email builder with a mjml output thats working fine for me. im using this version : https://github.com/m-Ryan/easy-email-demo but that is the main repo: https://github.com/arco-design/easy-email

augustinnoha commented 2 years ago

Hi guys exact same problem for me using VueJS. Can't get rid of this body tag added. So mjml compilation fails. Hop it could be resolved soon.

lphm commented 2 years ago

Same problem for me.

esafronov commented 2 years ago

This issue also happens to me. Check out this fiddle.

https://jsfiddle.net/zietbukuel/m1vcjgn5/2/

Hi I have the same issue but if you remove mjml tags in your example it will work.

zietbukuel commented 2 years ago

@esafronov still not working, the tag is still present, which shouldn't be the case.

atodared commented 2 years ago

Same behavior. Resolved fixing previous version 18.0.3 on grapes.js

Html:

NodeJs: npm i grapesjs@0.18.3

mlazovla commented 2 years ago

In changelog v0.18.4 is suggested to override wrapper component.

editor.Components.addType('wrapper', {
  model: {
    defaults: {
      tagName: 'div', // replace body to div
    },
    // And/or skip wrapper in the HTML output
    toHTML: function(opts) {
      return this.getInnerHTML(opts);
     }
  }
});

But it does not work for me, any suggestion?

esafronov commented 2 years ago

In changelog v0.18.4 is suggested to override wrapper component.

editor.Components.addType('wrapper', {
  model: {
    defaults: {
      tagName: 'div', // replace body to div
    },
    // And/or skip wrapper in the HTML output
    toHTML: function(opts) {
      return this.getInnerHTML(opts);
     }
  }
});

But it does not work for me, any suggestion?

Should be : tagName: 'mjml'

mlazovla commented 2 years ago

No, I have to remove body tag entirely.

It is like this:

<body>
  <mjml>
    <mj-head id="ilnn">
       <mj-raw>
       ...
  </mjml>
</body>

And it would be like this.

<mjml>
  <mj-head id="ilnn">
    <mj-raw>
     ...
</mjml>

The solution is to override wrapper component toHTML() method.

editor.getWrapper().toHTML = function(opts) {
  return this.getInnerHTML(opts);
};
manuel-84 commented 2 years ago

No, I have to remove body tag entirely.

It is like this:

<body>
  <mjml>
    <mj-head id="ilnn">
       <mj-raw>
       ...
  </mjml>
</body>

And it would be like this.

<mjml>
  <mj-head id="ilnn">
    <mj-raw>
     ...
</mjml>

The solution is to override wrapper component toHTML() method.

editor.getWrapper().toHTML = function(opts) {
  return this.getInnerHTML(opts);
};

overriding toHTML was enough for me, this is my starting container

        <div :id="id">
          <mjml v-pre>
            <mj-body>
              <mj-section>
                <mj-column>
                  <mj-text>Content</mj-text>
                </mj-column>
              </mj-section>
            </mj-body>
          </mjml>
        </div>
artf commented 1 year ago

This should be fixed in the latest release.