zalify / easy-email-editor

Easy Email Editor is a feature-rich, top open-source SaaS email editor based on React and MJML.
https://email.maocanhua.cn/
MIT License
1.59k stars 329 forks source link

Issue with MJML in custom block. #221

Closed Robw94 closed 1 year ago

Robw94 commented 1 year ago

Hello, I have been trying to follow the guide

https://github.com/zalify/easy-email/blob/master/Custom%20block.md

However, when trying to use MJML (other methods work fine) just wanted to use MJML because I can literally copy & paste the mjml code direct from editor for custom blocks. I am getting the following error:

Uncaught Error: Objects are not valid as a React child (found: object with keys {type, attributes, data, children}). If you meant to render a collection of children, use an array instead.

The code I am trying is a direct copy and paste from the provided one.

import { IBlock, IBlockData, BasicType, components, MjmlToJson } from 'easy-email-core';
import { CustomBlocksType } from '../constants';
import React from 'react';
import { merge } from 'lodash';

const { Section, Column, Image, Button } = components;

export type ICustomHeader = IBlockData<
  {
    'background-color': string;
    'text-color': string;
  },
  {
    buttonText: string;
    imageUrl: string
  }
>;

export const MyFirstBlock: IBlock = {
  name: 'My first block',
  type: CustomBlocksType.MY_FIRST_BLOCK,
  create(
    payload
  ) {
    const defaultData: ICustomHeader = {
      type: CustomBlocksType.MY_FIRST_BLOCK,
      data: {
        value: {
          buttonText: 'Got it',
          imageUrl: 'https://assets.maocanhua.cn/10dada65-c4fb-4b1f-837e-59a1005bbea6-image.png'
        },
      },
      attributes: {
        'background-color': '#4A90E2',
        'text-color': '#ffffff',
      },
      children: [],
    };
    return merge(defaultData, payload);
  },
  validParentType: [BasicType.PAGE, BasicType.WRAPPER],
  render(data: any) {

    // const attributes = data.attributes;
    // const { buttonText } = data.data.value;

    const instance = MjmlToJson(
      `<mj-button>test mjml</mj-button>`,
    );

    return instance;
  },
};

export { Panel } from './Panel'

I am using React 17.0.0 if tha tis an issue?

m-Ryan commented 1 year ago

Sorry, the documentation was not updated in time, I will update the documentation later.

You need to change to the following form.

 validParentType: [AdvancedType.COLUMN],
const { BlockRenderer } = components;
 render({ data, idx, mode, context, dataSource }) {
    const instance = MjmlToJson(
      `<mj-button background-color="red"  css-class="${
        mode === 'testing' ? getPreviewClassName(idx, data.type) : ''
      }">Hello</mj-button>`,
    ) as IBlockData;

    return <BlockRenderer data={instance} />;
  },
Robw94 commented 1 year ago

Hi Thanks this worked great.

However, I am still having an issue with the dynamic data (for loops).

I have cloned this project, ran locally on vite and when I click 'send' and copy and paste the HTML none of the product list is generating properly. However on your hosted version (demo) it works fine if I copy and paste the html to view it locally.

The merge tags that are not in a condition/loop work fine. Soon as I add a loop to a column they sotp working and no content is shown

m-Ryan commented 1 year ago

The logic block is implemented according to liquidjs, you can check the documentation of liquidjs https://liquidjs.com/