Hey! Just looking at the demo CMS on the website and checking out how rich text is formatted on the JSON output.
One thing I can't work out is why there are no elements for paragraphs i.e.
type: "paragraph"
for each entered paragraph? The default elements in the docs mention h1 to h6 and other elements, but no p tags.
I can't seem to decipher the code on the demo repository on Github either on how paragraph elements are being created.
How is this managed / converted?
Thanks so much!
Hi @_jeangabriel, but here's a quick explanation of how it's handled:
The elements shown in the docs example (
https://payloadcms.com/docs/fields/rich-text#example) are any formats that are not the default. Technically, your default format could be anything, but you can think of it as a
<p>
tag by default.
Below is an example of how we would generate the HTML on the frontend for Rich Text fields:
import React, { Fragment } from 'react';
import escapeHTML from 'escape-html';
import { Text } from 'slate';
const serialize = (children) => children.map((node, i) => {
if (Text.isText(node)) {
let text = <span dangerouslySetInnerHTML={{ __html: escapeHTML(node.text) }} />;
if (node.bold) {
text = (
<strong key={i}>
{text}
</strong>
);
}
if (node.code) {
text = (
<code key={i}>
{text}
</code>
);
}
if (node.italic) {
text = (
<em key={i}>
{text}
</em>
);
}
// Handle other leaf types here...
return (
<Fragment key={i}>
{text}
</Fragment>
);
}
if (!node) {
return null;
}
switch (node.type) {
case 'h1':
return (
<h1 key={i}>
{serialize(node.children)}
</h1>
);
// Iterate through all headings here...
case 'h6':
return (
<h6 key={i}>
{serialize(node.children)}
</h6>
);
case 'blockquote':
return (
<blockquote key={i}>
{serialize(node.children)}
</blockquote>
);
case 'ul':
return (
<ul key={i}>
{serialize(node.children)}
</ul>
);
case 'ol':
return (
<ol key={i}>
{serialize(node.children)}
</ol>
);
case 'li':
return (
<li key={i}>
{serialize(node.children)}
</li>
);
case 'link':
return (
<a
href={escapeHTML(node.url)}
key={i}
>
{serialize(node.children)}
</a>
);
default:
return (
<p key={i}>
{serialize(node.children)}
</p>
);
}
});
This is a
switch
statement that check the
case
of each node. Once it finds it, it wraps it in the correct HTML tag. Then, it runs the function again to the children of that node. This method iterates through any possible cases you define, and then if it doesn't find a specific case, it return the default case, which in the code above is a
<p>
element.
Star
Discord
online
Get help straight from the Payload team with an Enterprise License.