Add filter replacing written Personalization Tags to email editor
[MAILPOET-6376]
This commit is contained in:
committed by
Rostislav Wolný
parent
9b0cce9c0d
commit
041d76830b
@ -7,9 +7,14 @@ import {
|
|||||||
createTextToHtmlMap,
|
createTextToHtmlMap,
|
||||||
getCursorPosition,
|
getCursorPosition,
|
||||||
isMatchingComment,
|
isMatchingComment,
|
||||||
|
replacePersonalizationTagsWithHTMLComments,
|
||||||
} from '../../components/personalization-tags/rich-text-utils';
|
} from '../../components/personalization-tags/rich-text-utils';
|
||||||
import { PersonalizationTagsModal } from '../../components/personalization-tags/personalization-tags-modal';
|
import { PersonalizationTagsModal } from '../../components/personalization-tags/personalization-tags-modal';
|
||||||
import { useCallback, useState } from '@wordpress/element';
|
import { useCallback, useState } from '@wordpress/element';
|
||||||
|
import { addFilter } from '@wordpress/hooks';
|
||||||
|
import * as React from 'react';
|
||||||
|
import { storeName } from '../../store';
|
||||||
|
import { createHigherOrderComponent } from '@wordpress/compose';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Disable Rich text formats we currently cannot support
|
* Disable Rich text formats we currently cannot support
|
||||||
@ -121,4 +126,82 @@ function extendRichTextFormats() {
|
|||||||
} );
|
} );
|
||||||
}
|
}
|
||||||
|
|
||||||
export { disableCertainRichTextFormats, extendRichTextFormats };
|
const personalizationTagsLiveContentUpdate = createHigherOrderComponent(
|
||||||
|
( BlockEdit ) => ( props ) => {
|
||||||
|
const { attributes, setAttributes, name } = props;
|
||||||
|
const { content } = attributes;
|
||||||
|
|
||||||
|
// Fetch the personalization tags list
|
||||||
|
const list = useSelect(
|
||||||
|
( select ) => select( storeName ).getPersonalizationTagsList(),
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
|
||||||
|
// Memoized function to replace content tags
|
||||||
|
const updatedContent = useCallback( () => {
|
||||||
|
if ( ! content ) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
return replacePersonalizationTagsWithHTMLComments( content, list );
|
||||||
|
}, [ content, list ] );
|
||||||
|
|
||||||
|
// Handle content updates
|
||||||
|
const handleSetAttributes = useCallback(
|
||||||
|
( newAttributes ) => {
|
||||||
|
if ( newAttributes.content !== undefined ) {
|
||||||
|
const replacedContent =
|
||||||
|
replacePersonalizationTagsWithHTMLComments(
|
||||||
|
newAttributes.content,
|
||||||
|
list
|
||||||
|
);
|
||||||
|
setAttributes( {
|
||||||
|
...newAttributes,
|
||||||
|
content: replacedContent,
|
||||||
|
} );
|
||||||
|
} else {
|
||||||
|
setAttributes( newAttributes );
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[ list, setAttributes ]
|
||||||
|
);
|
||||||
|
|
||||||
|
// Only process supported blocks
|
||||||
|
if (
|
||||||
|
name === 'core/paragraph' ||
|
||||||
|
name === 'core/heading' ||
|
||||||
|
name === 'core/list-item'
|
||||||
|
) {
|
||||||
|
return (
|
||||||
|
<BlockEdit
|
||||||
|
{ ...props }
|
||||||
|
attributes={ {
|
||||||
|
...attributes,
|
||||||
|
content: updatedContent(),
|
||||||
|
} }
|
||||||
|
setAttributes={ handleSetAttributes }
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return default for unsupported blocks
|
||||||
|
return <BlockEdit { ...props } />;
|
||||||
|
},
|
||||||
|
'personalizationTagsLiveContentUpdate'
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Replace written personalization tags with HTML comments in real-time.
|
||||||
|
*/
|
||||||
|
function replaceWrittenPersonalizationTags() {
|
||||||
|
addFilter(
|
||||||
|
'editor.BlockEdit',
|
||||||
|
'mailpoet-email-editor/with-live-content-update',
|
||||||
|
personalizationTagsLiveContentUpdate
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export {
|
||||||
|
disableCertainRichTextFormats,
|
||||||
|
extendRichTextFormats,
|
||||||
|
replaceWrittenPersonalizationTags,
|
||||||
|
};
|
||||||
|
@ -11,6 +11,7 @@ import { disableImageFilter, hideExpandOnClick } from './core/image';
|
|||||||
import {
|
import {
|
||||||
disableCertainRichTextFormats,
|
disableCertainRichTextFormats,
|
||||||
extendRichTextFormats,
|
extendRichTextFormats,
|
||||||
|
replaceWrittenPersonalizationTags,
|
||||||
} from './core/rich-text';
|
} from './core/rich-text';
|
||||||
import { enhanceButtonBlock } from './core/button';
|
import { enhanceButtonBlock } from './core/button';
|
||||||
import { enhanceButtonsBlock } from './core/buttons';
|
import { enhanceButtonsBlock } from './core/buttons';
|
||||||
@ -29,6 +30,7 @@ export function initBlocks() {
|
|||||||
enhanceColumnsBlock();
|
enhanceColumnsBlock();
|
||||||
enhancePostContentBlock();
|
enhancePostContentBlock();
|
||||||
extendRichTextFormats();
|
extendRichTextFormats();
|
||||||
|
replaceWrittenPersonalizationTags();
|
||||||
alterSupportConfiguration();
|
alterSupportConfiguration();
|
||||||
registerCoreBlocks();
|
registerCoreBlocks();
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import * as React from '@wordpress/element';
|
import * as React from '@wordpress/element';
|
||||||
|
import { PersonalizationTag } from '../../store';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Maps indices of characters in HTML representation of the value to corresponding characters of stored value in RichText content. The stored value doesn't contain tags.
|
* Maps indices of characters in HTML representation of the value to corresponding characters of stored value in RichText content. The stored value doesn't contain tags.
|
||||||
@ -184,9 +185,35 @@ const isMatchingComment = (
|
|||||||
return htmlCommentRegex.test( substring );
|
return htmlCommentRegex.test( substring );
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Replace registered personalization tags with HTML comments in content.
|
||||||
|
* @param content string The content to replace the tags in.
|
||||||
|
* @param tags PersonalizationTag[] The tags to replace in the content.
|
||||||
|
*/
|
||||||
|
const replacePersonalizationTagsWithHTMLComments = (
|
||||||
|
content: string,
|
||||||
|
tags: PersonalizationTag[]
|
||||||
|
) => {
|
||||||
|
tags.forEach( ( tag ) => {
|
||||||
|
if ( ! content.includes( tag.token ) ) {
|
||||||
|
// Skip if the token is not in the content
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const escapedRegExp = tag.token.replace(
|
||||||
|
/[.*+?^${}()|[\]\\]/g,
|
||||||
|
'\\$&'
|
||||||
|
); // Escape special characters
|
||||||
|
const regex = new RegExp( `(?<!<!--)${ escapedRegExp }(?!-->)`, 'g' ); // Match token not inside HTML comments
|
||||||
|
content = content.replace( regex, `<!--${ tag.token }-->` );
|
||||||
|
} );
|
||||||
|
return content;
|
||||||
|
};
|
||||||
|
|
||||||
export {
|
export {
|
||||||
isMatchingComment,
|
isMatchingComment,
|
||||||
getCursorPosition,
|
getCursorPosition,
|
||||||
createTextToHtmlMap,
|
createTextToHtmlMap,
|
||||||
mapRichTextToValue,
|
mapRichTextToValue,
|
||||||
|
replacePersonalizationTagsWithHTMLComments,
|
||||||
};
|
};
|
||||||
|
Reference in New Issue
Block a user