Display WYSIWYG content (legacy)
WYSIWYG stands for What You See Is What You Get. It means that your back office users write their content without needing any HTML or React knowledge. This is the case in most CMS tools nowadays. The output though is usually HTML which does not necessarly match the React components you've built in your Front-Commerce application.
This is why we've built a theme/modules/Wysiwyg
component in Front-Commerce.
By default it takes a content
property which contains the HTML that needs to
be parsed, and transforms it in React components.
The <Wysiwyg />
component
The <Wysiwyg />
component applies two types of transformations to your HTML :
- shortcodes
- transforms
Shortcodes
Shortcodes are custom strings that can be parsed and transformed to HTML strings.
In Magento, they look like
{% raw %}{{gallery id="123" size="medium"}}{% endraw %}
. In Wordpress they are
like [gallery id="123" size="medium"]
. But ultimately, they can be whatever
string you want. The goal is to match a given regex, and transform it to some
HTML string.
For instance, for Magento, we parse {% raw %}{{media}}{% endraw %}
shortcodes
and replace them with <img>
tags. It looks like this:
{
// regex to identify the shortcode within your HTML code
regex: /\{\{media url="(.*?)"\}\}/gi,
// How to replace the given shortcode
replacement: (match, url) => `/media/${url}`
}
See EnhanceWysiwyg's reference for more details.
Transforms
Transforms are functions that take an HTML node and transform it in a React Element.
For instance, we want to make sure that it transforms <a>
tags to Link
elements to preserve React's navigation. For instance,
<a href="/about-us">About us</a>
will be transformed to
<Link to="/about-us">About us</Link>
. It looks like this:
export default (node, convertNodeToElement) => {
if (node.name === "a") {
const target = node.attribs && node.attribs.href;
const isExternal = !target || /^(https?:)?\/\//.test(target);
if (!isExternal) {
return (
<Link to={target} external={isExternal}>
{node.children.map(convertNodeToElement)}
</Link>
);
}
}
};
See EnhanceWysiwyg's reference for more details.
Platform specific Wysiwyg
components
Magento: theme/modules/Wysiwyg/MagentoWysiwyg
Shortcodes
Supported shortcodes:
{% raw %}{{media url="*"}}{% endraw %}
{% raw %}{{store url="*"}}{% endraw %}
{% raw %}{{widget type="*" attribute="value"}}{% endraw %}
Any other shortcode will be removed from your final content.
Transforms
<a>
tags are transformed to thetheme/components/atoms/Typography/Link
component when thehref
attribute does not contain a domain.<widget>
tags are transformedtheme/modules/Wysiwyg/MagentoWysiwyg/Widget
components. However, you shouldn't write a<widget>
tag manually. It is in fact coming from the{% raw %}{{widget}}{% endraw %}
shortcode.
Add a custom Magento Widget
Custom widgets will be automatically parsed. However, you will still need to map
the widget's type
to custom React Components. If you don't, they will be
ignored.
To do so, please override theme/modules/Wysiwyg/MagentoWysiwyg/Widget.js
in
your own theme.
mkdir -p src/web/theme/modules/Wysiwyg/MagentoWysiwyg/
cp node_modules/front-commerce/src/web/theme/modules/Wysiwyg/MagentoWysiwyg/Widget.js \
src/web/theme/modules/Wysiwyg/MagentoWysiwyg/Widget.js
Now, within your newly created Widget.js
file, you will be able to add your
own behavior. For instance, if you've created a widget in Magento with the type
acme/product-preview
, you will need to update the Widget.js
file likewise:
+import React from "react";
import PropTypes from "prop-types";
+//import your matching React Component
+import ProductPreview from "theme/modules/ProductPreview";
const Widget = ({ type, attributes }) => {
+ // And match the type with your component
+ if (type === "acme/product-preview") {
+ return <ProductPreview sku={attributes.sku} />
+ }
+
return null;
};
Widget.propTypes = {
type: PropTypes.string.isRequired,
attributes: PropTypes.object.isRequired
};
export default Widget;