Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Question: Is it possible to write an inline grapes-mjml custom component? (ie. no build system) #195

Closed
HeyWrecker opened this issue Aug 13, 2020 · 10 comments

Comments

@HeyWrecker
Copy link

Hello,

I'm working in an environment without a build system, so as a result I have to use the pre-built grapesjs-mjml plugin in my grapesjs.init(). I am trying to write a custom grapejs-mjml component as a function expression (ie. const customComponentTypes = (editor) => {}; that can then be included via the grapesjs.init() plugins list.

However, I'm running into the obvious problems of not having access to the coreMjmlModel and coreMjmlView expressions along with other utilities such as mjmlConvert since those are part of the pre-built plugin script and I have no way of importing them separately for inline use.

Is there any way to gain a reference to the utilities and expressions required to create an inline grapesjs-mjml component? Or, am I going to have to find a way to incorporate a build system into my project, clone the full grapesjs-mjml, write the component as a stand-alone component js file, and run a build to get a complete minified file?

const placeholderComponents = function(editor) {
    const type = 'spc-placeholder';
    editor.DomComponents.addType(type, {
        extend: 'text',
        extendFnView: ['onActive'],
        isComponent: function(el) {
            if (el.tagName === type.toUpperCase()) {
                return {
                    type: type,
                    content: el.innerHTML,
                    components: [],
                };
            }
        },
        model: {
            ...coreMjmlModel,
            defaults: {
                name: 'placeholder',
                draggable: '[data-gjs-type=mj-column], [data-gjs-type=mj-hero]',
                highlightable: false,
                stylable: [
                    'height', 'font-style', 'font-size', 'font-weight', 'font-family', 'color',
                    'line-height', 'letter-spacing', 'text-decoration', 'align', 'text-transform',
                    'padding', 'padding-top', 'padding-left', 'padding-right', 'padding-bottom',
                    'container-background-color'
                ],
                'style-default': {
                    'padding-top': '10px',
                    'padding-bottom': '10px',
                    'padding-right': '25px',
                    'padding-left': '25px',
                    'font-size': '13px',
                    'line-height': '22px',
                    'align': 'left',
                },
            },
        },
        view: {
            ...coreMjmlView,
            tagName: 'tr',
            attributes: {
            style: 'pointer-events: all; display: table; width: 100%',
        },
        getMjmlTemplate: function() {
            return {
                start: `<mjml><mj-body><mj-column>`,
                end: `</mj-column></mj-body></mjml>`,
            };
        },
        getTemplateFromEl: function(sandboxEl) {
            return sandboxEl.querySelector('tr').innerHTML;
        },
        getChildrenSelector: function() {
            return 'td > div';
        },
        /**
        * Prevent content repeating
        */
        renderChildren: function() {
            coreMjmlView.renderChildren.call(this);
        },
        /**
        * Need to make text selectable.
        */
        onActive: function() {
            this.getChildrenContainer().style.pointerEvents = 'all';
        },
     },
    });
};
@DRoet
Copy link
Collaborator

DRoet commented Aug 13, 2020

Are you looking to add a new mjml-component or do you just want to create a custom block that you can drag and drop into your editor?

To add a custom block you can add it to the BlockManager like so:

editor.BlockManager.add('custom-block', {
   category: 'section',
   label: '3/7 split',
   attributes: {
      title: '3/7 split',
      class: 'gjs-fonts gjs-f-b37'
   },
   class: 'gjs-fonts gjs-f-b37',
   content: `<mj-section background-color="#FFFFFF">
                <mj-column width="30%" border-radius="0 0 0 0" padding="10px">
                   <mj-text font-family="Roboto, Helvetica, sans-serif" font-size="17px" line-height="24px" color="#616161" align="center">
                      default text
                   </mj-text>
                </mj-column>
                <mj-column width="70%" border-radius="0 0 0 0" padding="10px">
                   <mj-text font-family="Roboto, Helvetica, sans-serif" font-size="17px" line-height="24px" color="#616161" align="center">
                      default text
                   </mj-text>
                </mj-column>
             </mj-section>`
})

If you want to add a new mjml component (for example mj-carousel) feel free to submit a PR and I can take a look to merge it in.

@HeyWrecker
Copy link
Author

HeyWrecker commented Aug 13, 2020

@DRoet actually, I think a custom block would work just fine. My use case is adding static custom placeholders (ex. [: email :] that would then get parsed server-side. So if I can do that as a block with a little mjml wrapping it, that should do nicely. That looks like what you're suggesting via the example.

const block_manager = editor.BlockManager;

block_manager.add('placeholder-location', {
    category: 'Placeholders',
    label: 'Location',
    content: '<mj-text>[: location :]</mj-text>',
    attributes: { class: 'gjs-fonts gjs-f-text' },
});

Is there a way to make a block like that not editable?

@DRoet
Copy link
Collaborator

DRoet commented Aug 14, 2020

Ok feel free to close this issue if it's resolved by using custom blocks

@HeyWrecker
Copy link
Author

I will. Thanks @DRoet Daan. Just a real quick question- how do I make the block read only?

@DRoet
Copy link
Collaborator

DRoet commented Aug 14, 2020

Have you tried using the disable property and using grapesjs > 0.16.12 ?

@HeyWrecker
Copy link
Author

I will look into it, thanks for the pointer!

@HeyWrecker
Copy link
Author

HeyWrecker commented Aug 17, 2020

@DRoet Hi Daan. I am using GrapesJS 0.16.18 and have tried configuring the block as follows:

block_manager.add('appointment-location-email', {
    category: 'Appointment Placeholders',
    label: 'Location - Email',
    content: '<mj-text>[:appointment_location_email:]</mj-text>',
    attributes: {
        class: 'gjs-fonts gjs-f-text',
        title: 'Drag to insert the appointment location email address placeholder.',
        disable: true
    },
 });

But the block continues to be editable (ie. I can double-click on it in the canvas and change the content). Am I configuring the block incorrectly? I did not see any documentation regarding making blocks read only in the GrapesJS docs or GrapesJS MJML Git site.

Additionally, I thought that the title attribute would provide a tooltip on hover, but it doesn't appear to be doing so using the text that I provided. Instead it seems to be defaulting the title value in the block panel to the label value.

@DRoet
Copy link
Collaborator

DRoet commented Aug 17, 2020

Hmm disable might not be the thing you are looking for, you could try and override some of the grapesjs-properties using data-gjs-{property name} on the block like this:

block_manager.add('appointment-location-email', {
    category: 'Appointment Placeholders',
    label: 'Location - Email',
    content: `<mj-text data-gjs-draggable="false" data-gjs-droppable="false" data-gjs-editable="false" data-gjs-hoverable="false" data-gjs-selectable="false" data-gjs-propagate="['draggable', 'droppable', 'editable', 'hoverable', 'selectable']">[:appointment_location_email:]</mj-text>`,
    attributes: {
        class: 'gjs-fonts gjs-f-text',
        title: 'Drag to insert the appointment location email address placeholder.'
    },
 });

You can read more on the properties here

@HeyWrecker
Copy link
Author

@DRoet Daan, that did it. Thank for the help! It was very much appreciated!

@RakulAgn
Copy link

Are you looking to add a new mjml-component or do you just want to create a custom block that you can drag and drop into your editor?

To add a custom block you can add it to the BlockManager like so:

editor.BlockManager.add('custom-block', {
   category: 'section',
   label: '3/7 split',
   attributes: {
      title: '3/7 split',
      class: 'gjs-fonts gjs-f-b37'
   },
   class: 'gjs-fonts gjs-f-b37',
   content: `<mj-section background-color="#FFFFFF">
                <mj-column width="30%" border-radius="0 0 0 0" padding="10px">
                   <mj-text font-family="Roboto, Helvetica, sans-serif" font-size="17px" line-height="24px" color="#616161" align="center">
                      default text
                   </mj-text>
                </mj-column>
                <mj-column width="70%" border-radius="0 0 0 0" padding="10px">
                   <mj-text font-family="Roboto, Helvetica, sans-serif" font-size="17px" line-height="24px" color="#616161" align="center">
                      default text
                   </mj-text>
                </mj-column>
             </mj-section>`
})

If you want to add a new mjml component (for example mj-carousel) feel free to submit a PR and I can take a look to merge it in.

Are you looking to add a new mjml-component or do you just want to create a custom block that you can drag and drop into your editor?

To add a custom block you can add it to the BlockManager like so:

editor.BlockManager.add('custom-block', {
   category: 'section',
   label: '3/7 split',
   attributes: {
      title: '3/7 split',
      class: 'gjs-fonts gjs-f-b37'
   },
   class: 'gjs-fonts gjs-f-b37',
   content: `<mj-section background-color="#FFFFFF">
                <mj-column width="30%" border-radius="0 0 0 0" padding="10px">
                   <mj-text font-family="Roboto, Helvetica, sans-serif" font-size="17px" line-height="24px" color="#616161" align="center">
                      default text
                   </mj-text>
                </mj-column>
                <mj-column width="70%" border-radius="0 0 0 0" padding="10px">
                   <mj-text font-family="Roboto, Helvetica, sans-serif" font-size="17px" line-height="24px" color="#616161" align="center">
                      default text
                   </mj-text>
                </mj-column>
             </mj-section>`
})

If you want to add a new mjml component (for example mj-carousel) feel free to submit a PR and I can take a look to merge it in.

hey @DRoet I am looking for creating something like this

A MJML CUSTOM COMPONENT and i need all mj-text stylables to mj-coupon and also i have doubt i need to create this tag through mjml after that i need to use the tag in grapesjs mjml but by default in grapesjs mjml in supported tag there is no option to support for custom tags

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants