diff --git a/ts/structure-in-rte/resolve_rich_text_components_items.tsx b/ts/structure-in-rte/resolve_rich_text_components_items.tsx index 03dd0472..bccacd19 100644 --- a/ts/structure-in-rte/resolve_rich_text_components_items.tsx +++ b/ts/structure-in-rte/resolve_rich_text_components_items.tsx @@ -1,60 +1,35 @@ import { Elements } from "@kontent-ai/delivery-sdk"; -import { - nodeParse, - PortableTextComponent, - transformToPortableText, -} from "@kontent-ai/rich-text-resolver"; -import { - PortableText, - PortableTextComponents, - PortableTextTypeComponentProps, -} from "@portabletext/react"; +import { PortableTextComponent } from "@kontent-ai/rich-text-resolver"; +import { PortableTextComponents, PortableTextTypeComponentProps, } from "@portabletext/react"; +import { React } from 'react'; import { CalloutComponent } from "../components/shared/richText/Callout"; import { contentTypes } from "../models"; - -type RichTextComponentProps = { - richTextElement: Elements.RichTextElement; -}; - -const getPortableTextComponents = ( - element: Elements.RichTextElement -): Partial => ({ +const createRichTextResolver = (element: Elements.RichTextElement): Partial => ({ types: { + // Components and content items inserted in rich text component: ({ value, }: PortableTextTypeComponentProps) => { + // Checks if the inserted content item is included in the response + // Kontent.ai components are always included in the response const componentOrItem = element.linkedItems.find( (i) => i.system.codename === value.component._ref ); if (!componentOrItem) { - throw new Error("Component or item not found."); + return (
The referenced content item '{componentOrItem.system.codename}' wasn't found.
); } + // Renders the component or content item based on its type switch (componentOrItem.system.type) { + // Tip: Generate models at https://kontent.ai/learn/strongly-typed-models case contentTypes.callout.codename: return ; default: - return ( -
- Resolution for content type {componentOrItem.system.type} not - implemented. -
- ); + return (
Content based on the type '{componentOrItem.system.type}' couldn't be resolved.
); } }, }, -}); - -export const RichTextComponent: React.FC = (props) => { - const parsedTree = nodeParse(props.richTextElement.value); - const portableText = transformToPortableText(parsedTree); - return ( - - ); -}; +}); \ No newline at end of file diff --git a/ts/structure-in-rte/resolve_rich_text_flow.tsx b/ts/structure-in-rte/resolve_rich_text_flow.tsx index a18c9292..f92ee172 100644 --- a/ts/structure-in-rte/resolve_rich_text_flow.tsx +++ b/ts/structure-in-rte/resolve_rich_text_flow.tsx @@ -1,42 +1,48 @@ import { Elements } from "@kontent-ai/delivery-sdk"; -import { - nodeParse, - transformToPortableText, -} from "@kontent-ai/rich-text-resolver"; -import { PortableText } from "@portabletext/react"; - -type RichTextComponentProps = { - richTextElement: Elements.RichTextElement; -}; +import { nodeParse, transformToPortableText, } from "@kontent-ai/rich-text-resolver"; +import { PortableText, PortableTextComponents } from "@portabletext/react"; +import { React } from "react"; // Defines how to transform Kontent.ai-specific portable text components, as well as default blocks -const portableTextComponents = { - // The logic for each portable text component is explained later in the lesson +const createRichTextResolver = (element: Elements.RichTextElement): Partial => ({ + // The logic for individual portable text components is explained later in the lesson types: { - component: undefined, // Components and linked items in rich text - table: undefined, // Tables in rich text - image: undefined, // Assets in rich text + // Resolution for components and content items inserted in rich text + component: undefined, + // Resolution for tables in rich text + table: undefined, + // Resolution for assets in rich text + image: undefined, }, marks: { - link: undefined, // Links to external URLs - internalLink: undefined, // Links to content items + // Resolution for links to external URLs + link: undefined, + // Resolution for links to content items + internalLink: undefined, }, block: { - // Custom resolution for default blocks - h1: undefined, // h1 heading - p: undefined, // paragraph + // Exmamples of custom resolution for default blocks + h1: undefined, // h1 headings + p: undefined, // paragraphs }, +}); + +type RichTextComponentProps = { + richTextElement: Elements.RichTextElement; }; // Custom React component that renders your rich text element export const RichTextComponent: React.FC = (props) => { - // Converts Kontent.ai rich text HTML to a JSON tree + // Converts a Kontent.ai rich text element value to a JSON tree const parsedTree = nodeParse(props.richTextElement.value); // Converts the JSON tree to portable text const portableText = transformToPortableText(parsedTree); - // Renders portable text based on the specified portable text component transformations + // Renders content based on the specified transformations return ( - + ); }; @@ -46,4 +52,4 @@ export const RichTextComponent: React.FC = (props) => { // Example: using 'MyComponent' to render your rich text element in a
//
// -//
+//
\ No newline at end of file diff --git a/ts/structure-in-rte/resolve_rich_text_links_to_items.tsx b/ts/structure-in-rte/resolve_rich_text_links_to_items.tsx index 7067f60e..3d667878 100644 --- a/ts/structure-in-rte/resolve_rich_text_links_to_items.tsx +++ b/ts/structure-in-rte/resolve_rich_text_links_to_items.tsx @@ -1,59 +1,19 @@ import { Elements, ILink } from "@kontent-ai/delivery-sdk"; -import { - nodeParse, - PortableTextInternalLink, - transformToPortableText, -} from "@kontent-ai/rich-text-resolver"; -import { - PortableText, - PortableTextComponents, - PortableTextMarkComponentProps, -} from "@portabletext/react"; -import { ReactNode } from "react"; +import { PortableTextInternalLink } from "@kontent-ai/rich-text-resolver"; +import { PortableTextComponents, PortableTextMarkComponentProps } from "@portabletext/react"; +import { React, ReactNode } from "react"; import { ProductLink } from "../components"; import { contentTypes } from "../models"; -type RichTextComponentProps = { - richTextElement: Elements.RichTextElement; -}; - -type ItemLinkProps = { +type ContentItemLinkProps = { link: ILink; children: ReactNode; }; -type ProductLinkProps = {}; - -const getPortableTextComponents = ( - element: Elements.RichTextElement -): Partial => ({ - marks: { - internalLink: ({ - value, - children, - }: PortableTextMarkComponentProps) => { - const link = element.links.find( - (l) => l.linkId === value?.reference._ref - ); - - return {children}; - }, - }, -}); - -export const RichTextComponent: React.FC = (props) => { - const parsedTree = nodeParse(props.richTextElement.value); - const portableText = transformToPortableText(parsedTree); - return ( - - ); -}; - -const ItemLink: React.FC = (props) => { +// Custom React component for rendering links to content items +const ContentItemLink: React.FC = (props) => { + // Use different resolution logic based on the content type switch (props.link.type) { case contentTypes.product.codename: return ( @@ -65,12 +25,28 @@ const ItemLink: React.FC = (props) => { ); default: - throw new Error( - `No resolution implemented for item links of type ${props.link.type}.` - ); + return (
Link to the content item '{props.link.codename}' couldn't be resolved.
); } }; +type ProductLinkProps = {}; const ProductLink: React.FC = (props) => { - // implementation of ProductLink component + // Based on your app routing, resolve links to products }; + +const createRichTextResolver = (element: Elements.RichTextElement): Partial => ({ + marks: { + // Links to content items + internalLink: ({ + value, // The linked item's metadata + children, // Link text that might include text formatting + }: PortableTextMarkComponentProps) => { + // Gets content item link metadata from the response + const link = element.links.find( + (l) => l.linkId === value?.reference._ref + ); + + return {children}; + }, + }, +}); \ No newline at end of file diff --git a/ts/structure-in-rte/structure_in_rte_use_standalone_resolver.tsx b/ts/structure-in-rte/structure_in_rte_use_standalone_resolver.tsx deleted file mode 100644 index 7cf96b7e..00000000 --- a/ts/structure-in-rte/structure_in_rte_use_standalone_resolver.tsx +++ /dev/null @@ -1,86 +0,0 @@ -import React from "react"; -import { PortableText, PortableTextComponentProps, PortableTextMarkComponentProps, PortableTextReactComponents, PortableTextTypeComponentProps, toPlainText } from "@portabletext/react"; -import { nodeParse, transformToPortableText } from "@kontent-ai/rich-text-resolver" -import { resolveImage, resolveTable, toHTMLImageDefault } from "@kontent-ai/rich-text-resolver/utils/html"; -import { PortableTextComponent, PortableTextTable, PortableTextImage, PortableTextExternalLink, PortableTextInternalLink, PortableTextBlock } from "@kontent-ai/rich-text-resolver/types/transformer" -import { Elements } from "@kontent-ai/delivery-sdk" - -const richTextElement: Elements.RichTextElement = {/* rich text element from SDK response */} - -/** - * object, defining resolution for various portable text objects. - * to be passed into component. - */ -const portableTextComponents: Partial = { - types: { - // resolution for component custom block, representing linked items/components in rich text content - component: ({ value }: PortableTextTypeComponentProps) => { - const item = richTextElement.linkedItems.find(item => item.system.codename === value.component._ref); - return
{item?.elements.text_element.value}
; - }, - // resolution for tables in rich text. - // makes use of resolveTable helper method included in the package. - table: ({ value }: PortableTextTypeComponentProps) => { - const tableString = resolveTable(value, toPlainText); - return <>{tableString}; - }, - // resolution for assets in rich text. - // makes use of resolveImage helper method included in the package. - image: ({ value }: PortableTextTypeComponentProps) => { - const imageString = resolveImage(value, toHTMLImageDefault); - return <>{imageString}; - } - }, - marks: { - // resolution for links to external URLs - link: ({ value, children }: PortableTextMarkComponentProps) => { - const target = (value?.href || '').startsWith('http') ? '_blank' : undefined - return ( - - {children} - - ) - }, - // resolution for links to content items - internalLink: ({ value, children }: PortableTextMarkComponentProps) => { - const item = richTextElement.linkedItems.find(item => item.system.id === value?.reference._ref); - return ( - - {children} - - ) - } - }, - block: { - /** - * custom resolution for h1 tag. this specific example showcases anchor creation. - * - * createAnchorString can return e.g. a sanitized, url-friendly text content - * of the heading or any other string representing the anchor. - * - * all default tags/blocks can be overridden in this manner. - */ - h1: ({ value, children }: PortableTextComponentProps) => ( -

- {children} -

- ), - }, - } - - // custom component rendering the resolved rich text - const MyComponent = ({ props }) => { - // https://github.com/portabletext/react-portabletext#customizing-components - - const parsedTree = nodeParse(props.element.value); // or browserParse, converts HTML to JSON tree - const portableText = transformToPortableText(parsedTree); // converts JSON tree to portable text - - return ( - /** - * component from @portabletext/react package. - * accepts an array of portable text blocks and the `components` object which - * defines resolution for individual portable text entities. - */ - - ); - }; \ No newline at end of file