Skip to main content

Easy Email Pro Core

The easy-email-pro-core package provides the foundational functionality for Easy Email Pro, including block management, MJML conversion, template rendering, and utility functions.

Installation​

pnpm install easy-email-pro-core

Methods​

EditorCore​

The EditorCore class provides static methods for converting between different formats and rendering templates.

toMJML(options: JsonToMjmlOption): string​

Converts an email template element to MJML string format. This is the primary method for generating email HTML.

Parameters:

  • options.element: The root element (usually a Page element) to convert
  • options.mode: "testing" or "production" - determines rendering mode
  • options.beautify: Optional boolean to format the output

Returns: MJML string

Example:

import { EditorCore } from "easy-email-pro-core";

const mjmlStr = EditorCore.toMJML({
element: templateContent,
mode: "production",
beautify: true,
});

// Then convert to HTML using mjml-browser
import mjml from "mjml-browser";
const { html } = mjml(mjmlStr);

elementToMjml(node, options): string​

Converts a single element (not the full page) to MJML string.

Example:

const sectionMjml = EditorCore.elementToMjml(sectionElement, {
pageElement: page,
mode: "production",
});

renderWithData(html: string, data: Record<string, any>): string​

Renders HTML with dynamic data using template engine syntax. Supports variables like {{user.name}}.

Example:

const html = "<p>Hello {{user.name}}</p>";
const rendered = EditorCore.renderWithData(html, {
user: { name: "John" },
});
// Result: "<p>Hello John</p>"

mjmlToBlockElement(mjml: string): Element​

Converts an MJML string back to an Element object. Useful for importing templates.

Example:

const mjmlString = '<mj-section><mj-column><mj-text>Hello</mj-text></mj-column></mj-section>';
const element = EditorCore.mjmlToBlockElement(mjmlString);

getUniversalElements(data: { content: Element }): Record<string, Array>​

Extracts all universal elements from a template. Universal elements are reusable components saved separately.

Example:

const universalElements = EditorCore.getUniversalElements({
content: templateContent,
});
// Returns: { "header": [...], "footer": [...] }

transformUniversalElements(data): Element​

Replaces universal element references with their actual content.

Example:

const transformed = EditorCore.transformUniversalElements({
content: templateWithUniversalElements,
universalElements: {
header: headerElement,
footer: footerElement,
},
});
export class EditorCore {
static toMJML(options: JsonToMjmlOption): string;

static elementToMjml(
node: NodeElement,
options: Omit<JsonToMjmlOption, "element"> & {
pageElement: NodeElement;
}
): string;

static renderWithData(html: string, data: Record<string, any>): string;

static isPageDataVariable(text: string): string;
static getPageDataVariables(
page: PageElement,
attributesVariables: Record<string, any>
): Record<string, any>;

static renderWithPageVariables<T extends Object | string>(
obj: T,
data?: Record<string, any>
): T;

static mjmlToBlockElement(mjml: string): Element;

static getUniversalElements(data: { content: Element }): Record<
string,
{
idx: string;
blockData: Element;
}[]
>;

static transformUniversalElements<
T extends {
content: Element;
universalElements: Record<string, Element>;
}
>(data: T): T["content"];

// static mjmlToJson see easy-email-pro-theme
}

BlockManager​

The BlockManager class handles registration and retrieval of block definitions. All blocks must be registered before they can be used in the editor.

registerBlocks(blocks: Array<ElementDefinition<any>>): void​

Registers one or more block definitions with the system. This must be called before using custom blocks.

Example:

import { BlockManager } from "easy-email-pro-core";
import { MyCustomBlock } from "./MyCustomBlock";

BlockManager.registerBlocks([MyCustomBlock]);

getBlockByType<T>(type: T): ElementDefinition​

Retrieves a block definition by its type. Returns the default data structure for that block type.

Example:

const textBlock = BlockManager.getBlockByType("standard-paragraph");
const defaultData = textBlock.defaultData;

getBlocks(): Array<ElementDefinition>​

Returns all registered block definitions.

Example:

const allBlocks = BlockManager.getBlocks();
allBlocks.forEach(block => {
console.log(block.name, block.type);
});

getBlockTitle(blockData: Element): string​

Gets the display title for a block instance. Useful for showing block names in the UI.

Example:

const title = BlockManager.getBlockTitle(selectedElement);
// Returns: "Text", "Image", "Button", etc.
export class BlockManager {
public static registerBlocks(blocks: Array<ElementDefinition<any>>): void;

public static getBlockByType<T extends Element["type"]>(type: T): ElementDefinition<T>;

public static getBlocks(): Array<ElementDefinition>;

public static getBlockTitle(blockData: Element): string;
}

NodeUtils​

The NodeUtils class provides utility functions for checking node types and relationships. These are essential for building custom functionality that needs to identify or filter specific elements.

Type Checking Methods​

All type checking methods return a boolean indicating whether the node matches the specified type.

Common Examples:

import { NodeUtils } from "easy-email-pro-core";

// Check if node is a text node (leaf node)
if (NodeUtils.isTextNode(node)) {
console.log("This is a text node");
}

// Check if node is an element (container node)
if (NodeUtils.isElement(node)) {
console.log("This is an element");
}

// Check specific element types
if (NodeUtils.isPageElement(node)) {
console.log("This is the page root");
}

if (NodeUtils.isSectionElement(node)) {
console.log("This is a section");
}

if (NodeUtils.isTextElement(node)) {
console.log("This is a text block");
}

if (NodeUtils.isImageElement(node)) {
console.log("This is an image block");
}

// Check for merge tags
if (NodeUtils.isMergetagElement(node)) {
console.log("This is a merge tag");
}

const text = "{{user.name}}";
if (NodeUtils.isMergeTag(text)) {
console.log("String contains a merge tag");
}

Category and Relationship Methods​

// Check element categories
if (NodeUtils.isContentElementCategory("TEXT")) {
console.log("TEXT is a content category");
}

// Check parent-child relationships
if (NodeUtils.isParentCategoryType("standard-paragraph", "standard-section")) {
console.log("Paragraph can be child of section");
}

Full API:

export class NodeUtils {
static isVoidBlockElement(node: TextNode | Node): boolean;

static isUnsetElement(node: TextNode | Node): boolean;

static isTextNode(node: TextNode | Node): boolean;

static isElement(node: TextNode | Node): boolean;

static isBlockElement(node: TextNode | Node): boolean;

static isUniversalElement(node: TextNode | Node): boolean;

static isInlineElement(node: TextNode | Node): boolean;

static isMergetagElement(node: TextNode | Node): boolean;

static isContentElementCategory(type: ElementCategoryType): boolean;

static isPageElement(node: Node | TextNode): boolean;

static isSectionElement(node: TextNode | Node): boolean;

static isWrapperElement(node: TextNode | Node): boolean;

static isGroupElement(node: TextNode | Node): boolean;

static isColumnElement(node: TextNode | Node): boolean;

static isContentElement(node: TextNode | Node): boolean;

static isTextElement(node: TextNode | Node): boolean;

static isImageElement(node: TextNode | Node): boolean;

static isPlaceholderElement(node: TextNode | Node): boolean;

static isTextListElement(node: TextNode | Node): boolean;

static isTextListItemElement(node: TextNode | Node): boolean;

static isMergeTag(value: string): boolean;

static isParentCategory(
cat: ElementCategoryType,
parentCat: ElementCategoryType
): boolean;

static isParentCategoryType(
childType: Element["type"],
parentType: Element["type"]
): boolean;
}

PluginManager​

The PluginManager class manages all plugins including template engines, responsive plugins, and element plugins. It provides static methods for template rendering and plugin registration.

Template Engine Methods:

The template engine functionality is provided through PluginManager after registering a TemplateEnginePlugin:

export class PluginManager {
// Template engine methods (available after registering TemplateEnginePlugin)
public static generateIterationTemplate: TemplateEnginePlugin["generateIterationTemplate"];
public static generateConditionTemplate: TemplateEnginePlugin["generateConditionTemplate"];
public static generateVariable: TemplateEnginePlugin["generateVariable"];
public static isVariable: TemplateEnginePlugin["isVariable"];
public static renderWithData: TemplateEnginePlugin["renderWithData"];

// Responsive methods (available after registering ResponsivePlugin)
public static enabledResponsive: boolean;
public static generateResponsive: ResponsivePlugin["generateResponsive"];

// Plugin registration
public static registerPlugin(Plug: new () => Plugin): void;
public static registerPlugins(plugins: Array<new () => Plugin>): void;
}

Usage Example:

import { PluginManager } from "easy-email-pro-core";

// Register a template engine plugin
PluginManager.registerPlugins([MyTemplateEnginePlugin]);

// Use template engine methods
const html = "<p>Hello {{user.name}}</p>";
const rendered = PluginManager.renderWithData(html, {
user: { name: "John" },
});
// Result: "<p>Hello John</p>"

Note: Template engine methods are available after registering a TemplateEnginePlugin. By default, the TemplateEngine plugin is registered automatically, which provides Liquid template syntax support.

Components​

  • BlockRenderer

  • BasicBlock

  • ContentLeaf

  • ContentEditableBlock

Elements​

export {
Wrapper,
Section,
Column,
Text,
Button,
Image,
Raw,
Spacer,
Group,
Divider,
Navbar,
NavbarLink,
Social,
SocialElement,
Hero,
ForEach,
Show,
};