From 2ea5bcae5acc83dc66bcbbbf06baef07186928d6 Mon Sep 17 00:00:00 2001 From: Richard Sustek Date: Tue, 17 Sep 2024 11:42:56 +0200 Subject: [PATCH 1/7] Removes RTE resolver from Delivery JS SDK --- .../build_first_js_app_article.html | 30 ------------ ...uild_first_js_app_article_1_createnodes.js | 49 ------------------- ...ild_first_js_app_article_2_resolvelinks.js | 14 ------ ...uild_first_js_app_article_3_queryconfig.js | 11 ----- ...build_first_js_app_article_4_renderhash.js | 5 -- ...ild_first_js_app_article_5_resolvevideo.js | 30 ------------ ...uild_first_js_app_article_6_queryconfig.js | 14 ------ .../build_first_js_app_article_7_error.js | 19 ------- ...structure_in_rte_resolve_links_to_items.js | 33 ------------- .../structure_in_rte_resolve_tweet.js | 38 -------------- ...structure_in_rte_resolve_links_to_items.ts | 40 --------------- .../structure_in_rte_resolve_tweet.ts | 44 ----------------- 12 files changed, 327 deletions(-) delete mode 100644 js/build-first-app/build_first_js_app_article.html delete mode 100644 js/build-first-app/build_first_js_app_article_1_createnodes.js delete mode 100644 js/build-first-app/build_first_js_app_article_2_resolvelinks.js delete mode 100644 js/build-first-app/build_first_js_app_article_3_queryconfig.js delete mode 100644 js/build-first-app/build_first_js_app_article_4_renderhash.js delete mode 100644 js/build-first-app/build_first_js_app_article_5_resolvevideo.js delete mode 100644 js/build-first-app/build_first_js_app_article_6_queryconfig.js delete mode 100644 js/build-first-app/build_first_js_app_article_7_error.js delete mode 100644 js/structure-in-rte/structure_in_rte_resolve_links_to_items.js delete mode 100644 js/structure-in-rte/structure_in_rte_resolve_tweet.js delete mode 100644 ts/structure-in-rte/structure_in_rte_resolve_links_to_items.ts delete mode 100644 ts/structure-in-rte/structure_in_rte_resolve_tweet.ts diff --git a/js/build-first-app/build_first_js_app_article.html b/js/build-first-app/build_first_js_app_article.html deleted file mode 100644 index 29bb186d..00000000 --- a/js/build-first-app/build_first_js_app_article.html +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - - Article - - - - - -
-

Articles

-
-
- - - - - - - - diff --git a/js/build-first-app/build_first_js_app_article_1_createnodes.js b/js/build-first-app/build_first_js_app_article_1_createnodes.js deleted file mode 100644 index e724f865..00000000 --- a/js/build-first-app/build_first_js_app_article_1_createnodes.js +++ /dev/null @@ -1,49 +0,0 @@ -// Define which article is being retrieved -const articleSlug = location.hash.slice(1); - -// Create article container -const articleContainer = addToElementbyId('div', 'article', app); - -// Call for article info -deliveryClient - .items() - .type('article') - .equalsFilter('elements.url_pattern', articleSlug) - .toPromise() - .then(response => { - // Check if article found before adding - const article = - response.data.items && response.data.items.length ? response.data.items[0] : undefined; - - // Update title - document.title = `Article | ${article.system.name}`; - - // Create nodes - const headerImage = createElement( - 'img', - 'article-header', - 'src', - article.elements.teaser_image.value[0].url - ); - const title = createElement( - 'h2', - 'article-title', - 'innerText', - article.elements.title.value - ); - const richTextElement = article.elements.body_copy; - const rteResolver = Kk.createRichTextHtmlResolver().resolveRichText({ - element: richTextElement, - // Here you'll define your resolvers - }); - const body = createElement( - 'div', - 'article-description', - 'innerHTML', - rteResolver.html - ); - - // Add nodes to DOM - articleContainer.append(headerImage, title, body); - return; - }); diff --git a/js/build-first-app/build_first_js_app_article_2_resolvelinks.js b/js/build-first-app/build_first_js_app_article_2_resolvelinks.js deleted file mode 100644 index c01d7c64..00000000 --- a/js/build-first-app/build_first_js_app_article_2_resolvelinks.js +++ /dev/null @@ -1,14 +0,0 @@ -const rteResolver = Kk.createRichTextHtmlResolver().resolveRichText({ - element: richTextElement, - linkedItems: Kk.linkedItemsHelper.convertLinkedItemsToArray(response.data.linkedItems), - urlResolver: (linkId, linkText, link) => { - // Set link based on type - const urlLocation = - link.type === 'article' - ? `article.html#${link.urlSlug}` - : link.type === 'coffee' - ? `coffee.html#${link.urlSlug}` - : 'unsupported-link'; - return { linkUrl: urlLocation }; - }, -}); diff --git a/js/build-first-app/build_first_js_app_article_3_queryconfig.js b/js/build-first-app/build_first_js_app_article_3_queryconfig.js deleted file mode 100644 index 9111637c..00000000 --- a/js/build-first-app/build_first_js_app_article_3_queryconfig.js +++ /dev/null @@ -1,11 +0,0 @@ -deliveryClient - .items() - .type('article') - .equalsFilter('elements.url_pattern', articleSlug) - .queryConfig({ - urlSlugResolver: (link, context) => { - return resolveUrl(link); - }, - }) - .toPromise() - // Continue as above diff --git a/js/build-first-app/build_first_js_app_article_4_renderhash.js b/js/build-first-app/build_first_js_app_article_4_renderhash.js deleted file mode 100644 index 684f2ffe..00000000 --- a/js/build-first-app/build_first_js_app_article_4_renderhash.js +++ /dev/null @@ -1,5 +0,0 @@ -// Reload page on hash change -const renderHash = () => { - window.history.go(); -}; -window.addEventListener('hashchange', renderHash, false); diff --git a/js/build-first-app/build_first_js_app_article_5_resolvevideo.js b/js/build-first-app/build_first_js_app_article_5_resolvevideo.js deleted file mode 100644 index d11d1234..00000000 --- a/js/build-first-app/build_first_js_app_article_5_resolvevideo.js +++ /dev/null @@ -1,30 +0,0 @@ -const rteResolver = Kk.createRichTextHtmlResolver().resolveRichText({ - element: richTextElement, - linkedItems: Kk.linkedItemsHelper.convertLinkedItemsToArray(response.data.linkedItems), - urlResolver: (linkId, linkText, link) => { - // Your link resolution logic - }, - contentItemResolver: (itemId, item) => { - if (item.system.type === 'hosted_video') { - const videoID = item.elements.video_id.value; - - // Check if a video host exists - const videoHost = - item.elements.video_host.value && item.elements.video_host.value.length - ? item.elements.video_host.value[0].codename - : undefined; - if (videoHost) { - // Return based on hosting provider - const htmlCode = videoHost === 'youtube' - ? `` - : ``; - return { - contentItemHtml: htmlCode - }; - } - } - return { - contentItemHtml: '' - }; - } -}); diff --git a/js/build-first-app/build_first_js_app_article_6_queryconfig.js b/js/build-first-app/build_first_js_app_article_6_queryconfig.js deleted file mode 100644 index 3a2238a5..00000000 --- a/js/build-first-app/build_first_js_app_article_6_queryconfig.js +++ /dev/null @@ -1,14 +0,0 @@ -deliveryClient - .items() - .type('article') - .equalsFilter('elements.url_pattern', articleSlug) - .queryConfig({ - urlSlugResolver: (link, context) => { - return resolveUrl(link); - }, - richTextResolver: (item, context) => { - return resolveLinkedItems(item); - } - }) - .toPromise() - // Continue as above diff --git a/js/build-first-app/build_first_js_app_article_7_error.js b/js/build-first-app/build_first_js_app_article_7_error.js deleted file mode 100644 index b0f31b26..00000000 --- a/js/build-first-app/build_first_js_app_article_7_error.js +++ /dev/null @@ -1,19 +0,0 @@ -deliveryClient - .items() - .type('article') - .equalsFilter('elements.url_pattern', articleSlug) - .toPromise() - .then(response => { - // Check if article found before adding - const article = - response.data.items && response.data.items.length ? response.data.items[0] : undefined; - - // 404 message if not found - if (!article) { - app.innerHTML = '

That article could not be found.

'; - return; - } - }) - .catch(err => { - reportErrors(err); - }); diff --git a/js/structure-in-rte/structure_in_rte_resolve_links_to_items.js b/js/structure-in-rte/structure_in_rte_resolve_links_to_items.js deleted file mode 100644 index d2241708..00000000 --- a/js/structure-in-rte/structure_in_rte_resolve_links_to_items.js +++ /dev/null @@ -1,33 +0,0 @@ -const KontentDelivery = require('@kontent-ai/delivery-sdk'); - -// Initializes the Delivery client -const deliveryClient = KontentDelivery.createDeliveryClient({ - environmentId: '', -}); - -// Gets your content item -const response = await deliveryClient.item('my_article') - .toPromise(); - -// Stores the contents of the rich text element -const richTextElement = response.data.item.elements.body; - -// Note: The code below executes correctly in browser. To adjust the code for nodejs, see https://kontent.ai/learn/js-rte-nodejs -// Defines how to resolve the rich text element -const resolvedRichText = KontentDelivery.createRichTextHtmlResolver().resolveRichText({ - // Gives the resolver the contents of your rich text - element: richTextElement, - urlResolver: (linkId, linkText, link) => { - let url = '#unsupported-link-type'; - // Checks the content type of the linked content item - if (link.type === 'article') - url = `/articles/${link.urlSlug}`; - return { - linkHtml: `${url}`, - // You can also return a plain URL - linkUrl: url, - }; -}); - -// Gets the resolved HTML content of your rich text -const resolvedRichTextHtml = resolvedRichText.html; diff --git a/js/structure-in-rte/structure_in_rte_resolve_tweet.js b/js/structure-in-rte/structure_in_rte_resolve_tweet.js deleted file mode 100644 index e034f04b..00000000 --- a/js/structure-in-rte/structure_in_rte_resolve_tweet.js +++ /dev/null @@ -1,38 +0,0 @@ -const KontentDelivery = require('@kontent-ai/delivery-sdk'); - -// Initializes the Delivery client -const deliveryClient = KontentDelivery.createDeliveryClient({ - environmentId: '', -}); - -// Gets your content item -const response = await deliveryClient.item('my_article') - .toPromise(); - -// Stores the contents of the rich text element -const richTextElement = response.data.item.elements.body; - -// Note: The code below executes correctly in browser. To adjust the code for nodejs, see https://kontent.ai/learn/js-rte-nodejs -// Defines how to resolve the rich text element -const resolvedRichText = KontentDelivery.createRichTextHtmlResolver().resolveRichText({ - // Gives the resolver the contents of your rich text - element: richTextElement, - // Points the resolver to the content items and components that might be used in the rich text element - linkedItems: KontentDelivery.linkedItemsHelper.convertLinkedItemsToArray(response.data.linkedItems), - contentItemResolver: (contentItem) => { - // For tweet items and components, resolves to the following HTML markup - if (contentItem && contentItem.system.type === 'tweet') { - return { - contentItemHtml: `` - }; - } - - // For other type of items and components, resolves to an empty string - return { - contentItemHtml: `
Unsupported type ${contentItem.system.type}
` - }; - } -}); - -// Gets the resolved HTML content of your rich text -const resolvedRichTextHtml = resolvedRichText.html; diff --git a/ts/structure-in-rte/structure_in_rte_resolve_links_to_items.ts b/ts/structure-in-rte/structure_in_rte_resolve_links_to_items.ts deleted file mode 100644 index de185ed7..00000000 --- a/ts/structure-in-rte/structure_in_rte_resolve_links_to_items.ts +++ /dev/null @@ -1,40 +0,0 @@ -// Tip: Find more about JS/TS SDKs at https://kontent.ai/learn/javascript -import { createRichTextHtmlResolver, Elements, createDeliveryClient, linkedItemsHelper, IContentItem } from '@kontent-ai/delivery-sdk'; - -// Initializes the Delivery client -const deliveryClient = createDeliveryClient({ - environmentId: '' -}); - -// Tip: Create strongly typed models according to https://kontent.ai/learn/strongly-typed-models -export type Article = IContentItem<{ - title: Elements.TextElement; - body: Elements.RichTextElement; -}>; - -// Gets your content item -const response = await deliveryClient.item
('my_article') - .toPromise(); - -// Stores the contents of the rich text element -const richTextElement = response.data.item.elements.body; - -// Note: The code below executes correctly in browser. To adjust the code for nodejs, see https://kontent.ai/learn/js-rte-nodejs -// Defines how to resolve the rich text element -const resolvedRichText = createRichTextHtmlResolver().resolveRichText({ - // Gives the resolver the contents of your rich text. - element: richTextElement, - urlResolver: (linkId, linkText, link) => { - let url = '#unsupported-link-type'; - // Checks the content type of the linked content item - if (link.type === 'article') - url = `/articles/${link.urlSlug}`; - return { - linkHtml: `${url}`, - // You can also return a plain URL - linkUrl: url, - }; - } -}); - -const resolvedHtml = resolvedRichText.html; diff --git a/ts/structure-in-rte/structure_in_rte_resolve_tweet.ts b/ts/structure-in-rte/structure_in_rte_resolve_tweet.ts deleted file mode 100644 index 6521d1c0..00000000 --- a/ts/structure-in-rte/structure_in_rte_resolve_tweet.ts +++ /dev/null @@ -1,44 +0,0 @@ -// Tip: Find more about JS/TS SDKs at https://kontent.ai/learn/javascript -import { createRichTextHtmlResolver, Elements, createDeliveryClient, linkedItemsHelper, IContentItem } from '@kontent-ai/delivery-sdk'; - -const deliveryClient = createDeliveryClient({ - environmentId: '' -}); - -// Tip: Create strongly typed models according to https://kontent.ai/learn/strongly-typed-models -export type Article = IContentItem<{ - title: Elements.TextElement; - body: Elements.RichTextElement; -}>; - -// Gets your content item with the rich text element -const response = await deliveryClient.item
('my_article') - .toPromise(); - -// Gets the contents of the rich text element -const richTextElement = response.data.item.elements.body; - -// Note: The code below executes correctly in browser. To adjust the code for nodejs, see https://kontent.ai/learn/js-rte-nodejs -// Defines how to resolve the rich text element -const resolvedRichText = createRichTextHtmlResolver().resolveRichText({ - // Gives the resolver the contents of your rich text - element: richTextElement, - // Points the resolver to the content items and components that might be used in the rich text element - linkedItems: linkedItemsHelper.convertLinkedItemsToArray(response.data.linkedItems), - contentItemResolver: (itemId, contentItem) => { - // For tweet items and components, resolves to the following HTML markup - if (contentItem && contentItem.system.type === 'tweet') { - return { - contentItemHtml: `` - }; - } - - // For other type of items and components, resolves to an empty string - return { - contentItemHtml: `
Unsupported type ${contentItem.system.type}
` - }; - } -}); - -// Gets the resolved HTML content of your rich text -const resolvedRichTextHtml = resolvedRichText.html; From c68d0dbe7a20a8a8fcc1d34453cdb6432ff4b124 Mon Sep 17 00:00:00 2001 From: Jan Cerman Date: Tue, 24 Sep 2024 15:20:16 +0200 Subject: [PATCH 2/7] CTC-2582 Remove build first app in JS --- .../build_first_js_app_articlelist_1.js | 2 - ...rst_js_app_articlelist_2_deliveryclient.js | 8 ---- ..._first_js_app_articlelist_3_createnodes.js | 21 --------- ...ild_first_js_app_articlelist_4_fulllist.js | 43 ------------------- .../build_first_js_app_articlelist_5_error.js | 10 ----- ...uild_first_js_app_core_1_main_constants.js | 10 ----- ...ild_first_js_app_core_2_delivery_client.js | 5 --- ...build_first_js_app_core_3_createelement.js | 18 -------- .../build_first_js_app_core_4_reporterror.js | 5 --- .../build_first_js_app_index.html | 25 ----------- 10 files changed, 147 deletions(-) delete mode 100644 js/build-first-app/build_first_js_app_articlelist_1.js delete mode 100644 js/build-first-app/build_first_js_app_articlelist_2_deliveryclient.js delete mode 100644 js/build-first-app/build_first_js_app_articlelist_3_createnodes.js delete mode 100644 js/build-first-app/build_first_js_app_articlelist_4_fulllist.js delete mode 100644 js/build-first-app/build_first_js_app_articlelist_5_error.js delete mode 100644 js/build-first-app/build_first_js_app_core_1_main_constants.js delete mode 100644 js/build-first-app/build_first_js_app_core_2_delivery_client.js delete mode 100644 js/build-first-app/build_first_js_app_core_3_createelement.js delete mode 100644 js/build-first-app/build_first_js_app_core_4_reporterror.js delete mode 100644 js/build-first-app/build_first_js_app_index.html diff --git a/js/build-first-app/build_first_js_app_articlelist_1.js b/js/build-first-app/build_first_js_app_articlelist_1.js deleted file mode 100644 index 9132d2d1..00000000 --- a/js/build-first-app/build_first_js_app_articlelist_1.js +++ /dev/null @@ -1,2 +0,0 @@ -// Add list container to app -const articleList = addToElementbyId('div', 'article-list', app); diff --git a/js/build-first-app/build_first_js_app_articlelist_2_deliveryclient.js b/js/build-first-app/build_first_js_app_articlelist_2_deliveryclient.js deleted file mode 100644 index c4cbcf89..00000000 --- a/js/build-first-app/build_first_js_app_articlelist_2_deliveryclient.js +++ /dev/null @@ -1,8 +0,0 @@ -// Call for a list of all articles -deliveryClient - .items() - .type('article') - .toPromise() - .then(response => { - console.log(response) - }); diff --git a/js/build-first-app/build_first_js_app_articlelist_3_createnodes.js b/js/build-first-app/build_first_js_app_articlelist_3_createnodes.js deleted file mode 100644 index 56221ed2..00000000 --- a/js/build-first-app/build_first_js_app_articlelist_3_createnodes.js +++ /dev/null @@ -1,21 +0,0 @@ -deliveryClient - .items() - .type('article') - .toPromise() - .then(response => { - response.data.items.forEach(item => { - // Create nodes - const card = createElement('div', 'card'); - card.classList.add('card-no-link-style'); - const link = createElement( - 'a', - 'link', - 'href', - './article.html#' + item.elements.url_pattern.value - ); - - // Add nodes to DOM - articleList.appendChild(card); - card.appendChild(link); - }); - }); diff --git a/js/build-first-app/build_first_js_app_articlelist_4_fulllist.js b/js/build-first-app/build_first_js_app_articlelist_4_fulllist.js deleted file mode 100644 index 2fbbe670..00000000 --- a/js/build-first-app/build_first_js_app_articlelist_4_fulllist.js +++ /dev/null @@ -1,43 +0,0 @@ -deliveryClient - .items() - .type('article') - .toPromise() - .then(response => { - response.data.items.forEach(item => { - // Create nodes - const card = createElement('div', 'card'); - card.classList.add('card-no-link-style'); - const link = createElement( - 'a', - 'link', - 'href', - './article.html#' + item.elements.url_pattern.value - ); - - const teaser = createElement( - 'img', - 'article-teaser', - 'src', - item.elements.teaser_image.value && item.elements.teaser_image.value.length - ? item.elements.teaser_image.value[0].url + '?w=500&h=500' - : undefined - ); - const title = createElement( - 'h2', - 'article-title', - 'innerText', - item.elements.title.value - ); - const description = createElement( - 'div', - 'article-description', - 'innerHTML', - item.elements.summary.value - ); - - // Add nodes to DOM - articleList.appendChild(card); - card.appendChild(link); - link.append(teaser, title, description); - }); - }); diff --git a/js/build-first-app/build_first_js_app_articlelist_5_error.js b/js/build-first-app/build_first_js_app_articlelist_5_error.js deleted file mode 100644 index f7bf65a0..00000000 --- a/js/build-first-app/build_first_js_app_articlelist_5_error.js +++ /dev/null @@ -1,10 +0,0 @@ -deliveryClient - .items() - .type('article') - .toPromise() - .then(response => { - // Your current code - }) - .catch(err => { - reportErrors(err); - }); diff --git a/js/build-first-app/build_first_js_app_core_1_main_constants.js b/js/build-first-app/build_first_js_app_core_1_main_constants.js deleted file mode 100644 index 645ff558..00000000 --- a/js/build-first-app/build_first_js_app_core_1_main_constants.js +++ /dev/null @@ -1,10 +0,0 @@ -// Define main container -const app = document.getElementById('app'); - -// Function for creating and appending elements -const addToElementbyId = (elementType, id, parent) => { - const element = document.createElement(elementType); - element.setAttribute('id', id); - parent.appendChild(element); - return element; -}; diff --git a/js/build-first-app/build_first_js_app_core_2_delivery_client.js b/js/build-first-app/build_first_js_app_core_2_delivery_client.js deleted file mode 100644 index bb499ea7..00000000 --- a/js/build-first-app/build_first_js_app_core_2_delivery_client.js +++ /dev/null @@ -1,5 +0,0 @@ -// Set up Delivery client -const Kk = window['kontentDelivery']; -const deliveryClient = new Kk.createDeliveryClient({ - environmentId: '975bf280-fd91-488c-994c-2f04416e5ee3' -}); diff --git a/js/build-first-app/build_first_js_app_core_3_createelement.js b/js/build-first-app/build_first_js_app_core_3_createelement.js deleted file mode 100644 index 94c3474e..00000000 --- a/js/build-first-app/build_first_js_app_core_3_createelement.js +++ /dev/null @@ -1,18 +0,0 @@ -// Function for adding elements to DOM with specific attributes -const createElement = (elementType, classToAdd, attribute, attributeValue) => { - const element = document.createElement(elementType); - element.setAttribute('class', classToAdd); - - // Set attribute value based on the attribute required - attribute === 'href' - ? (element.href = attributeValue) - : attribute === 'innerHTML' - ? (element.innerHTML = attributeValue) - : attribute === 'innerText' - ? (element.innerText = attributeValue) - : attribute === 'src' - ? (element.src = attributeValue) - : undefined; - - return element; - }; diff --git a/js/build-first-app/build_first_js_app_core_4_reporterror.js b/js/build-first-app/build_first_js_app_core_4_reporterror.js deleted file mode 100644 index 65faf3f5..00000000 --- a/js/build-first-app/build_first_js_app_core_4_reporterror.js +++ /dev/null @@ -1,5 +0,0 @@ -// Error messages -const reportErrors = err => { - console.error(err); - app.innerHTML = `

An error occured 😞:

${err}

`; -}; diff --git a/js/build-first-app/build_first_js_app_index.html b/js/build-first-app/build_first_js_app_index.html deleted file mode 100644 index beabcc1a..00000000 --- a/js/build-first-app/build_first_js_app_index.html +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - - Kontent.ai JavaScript sample app - - - - -
-

Articles

-
-
- - - - - - - - From 886c3ca7876d12815b8a9eb6912efc350f7bfa85 Mon Sep 17 00:00:00 2001 From: Jan Cerman Date: Tue, 24 Sep 2024 15:20:36 +0200 Subject: [PATCH 3/7] Revert "Removes RTE resolver from Delivery JS SDK" This reverts commit 2ea5bcae5acc83dc66bcbbbf06baef07186928d6. --- .../build_first_js_app_article.html | 30 ++++++++++++ ...uild_first_js_app_article_1_createnodes.js | 49 +++++++++++++++++++ ...ild_first_js_app_article_2_resolvelinks.js | 14 ++++++ ...uild_first_js_app_article_3_queryconfig.js | 11 +++++ ...build_first_js_app_article_4_renderhash.js | 5 ++ ...ild_first_js_app_article_5_resolvevideo.js | 30 ++++++++++++ ...uild_first_js_app_article_6_queryconfig.js | 14 ++++++ .../build_first_js_app_article_7_error.js | 19 +++++++ ...structure_in_rte_resolve_links_to_items.js | 33 +++++++++++++ .../structure_in_rte_resolve_tweet.js | 38 ++++++++++++++ ...structure_in_rte_resolve_links_to_items.ts | 40 +++++++++++++++ .../structure_in_rte_resolve_tweet.ts | 44 +++++++++++++++++ 12 files changed, 327 insertions(+) create mode 100644 js/build-first-app/build_first_js_app_article.html create mode 100644 js/build-first-app/build_first_js_app_article_1_createnodes.js create mode 100644 js/build-first-app/build_first_js_app_article_2_resolvelinks.js create mode 100644 js/build-first-app/build_first_js_app_article_3_queryconfig.js create mode 100644 js/build-first-app/build_first_js_app_article_4_renderhash.js create mode 100644 js/build-first-app/build_first_js_app_article_5_resolvevideo.js create mode 100644 js/build-first-app/build_first_js_app_article_6_queryconfig.js create mode 100644 js/build-first-app/build_first_js_app_article_7_error.js create mode 100644 js/structure-in-rte/structure_in_rte_resolve_links_to_items.js create mode 100644 js/structure-in-rte/structure_in_rte_resolve_tweet.js create mode 100644 ts/structure-in-rte/structure_in_rte_resolve_links_to_items.ts create mode 100644 ts/structure-in-rte/structure_in_rte_resolve_tweet.ts diff --git a/js/build-first-app/build_first_js_app_article.html b/js/build-first-app/build_first_js_app_article.html new file mode 100644 index 00000000..29bb186d --- /dev/null +++ b/js/build-first-app/build_first_js_app_article.html @@ -0,0 +1,30 @@ + + + + + + + + + + Article + + + + + +
+

Articles

+
+
+ + + + + + + + diff --git a/js/build-first-app/build_first_js_app_article_1_createnodes.js b/js/build-first-app/build_first_js_app_article_1_createnodes.js new file mode 100644 index 00000000..e724f865 --- /dev/null +++ b/js/build-first-app/build_first_js_app_article_1_createnodes.js @@ -0,0 +1,49 @@ +// Define which article is being retrieved +const articleSlug = location.hash.slice(1); + +// Create article container +const articleContainer = addToElementbyId('div', 'article', app); + +// Call for article info +deliveryClient + .items() + .type('article') + .equalsFilter('elements.url_pattern', articleSlug) + .toPromise() + .then(response => { + // Check if article found before adding + const article = + response.data.items && response.data.items.length ? response.data.items[0] : undefined; + + // Update title + document.title = `Article | ${article.system.name}`; + + // Create nodes + const headerImage = createElement( + 'img', + 'article-header', + 'src', + article.elements.teaser_image.value[0].url + ); + const title = createElement( + 'h2', + 'article-title', + 'innerText', + article.elements.title.value + ); + const richTextElement = article.elements.body_copy; + const rteResolver = Kk.createRichTextHtmlResolver().resolveRichText({ + element: richTextElement, + // Here you'll define your resolvers + }); + const body = createElement( + 'div', + 'article-description', + 'innerHTML', + rteResolver.html + ); + + // Add nodes to DOM + articleContainer.append(headerImage, title, body); + return; + }); diff --git a/js/build-first-app/build_first_js_app_article_2_resolvelinks.js b/js/build-first-app/build_first_js_app_article_2_resolvelinks.js new file mode 100644 index 00000000..c01d7c64 --- /dev/null +++ b/js/build-first-app/build_first_js_app_article_2_resolvelinks.js @@ -0,0 +1,14 @@ +const rteResolver = Kk.createRichTextHtmlResolver().resolveRichText({ + element: richTextElement, + linkedItems: Kk.linkedItemsHelper.convertLinkedItemsToArray(response.data.linkedItems), + urlResolver: (linkId, linkText, link) => { + // Set link based on type + const urlLocation = + link.type === 'article' + ? `article.html#${link.urlSlug}` + : link.type === 'coffee' + ? `coffee.html#${link.urlSlug}` + : 'unsupported-link'; + return { linkUrl: urlLocation }; + }, +}); diff --git a/js/build-first-app/build_first_js_app_article_3_queryconfig.js b/js/build-first-app/build_first_js_app_article_3_queryconfig.js new file mode 100644 index 00000000..9111637c --- /dev/null +++ b/js/build-first-app/build_first_js_app_article_3_queryconfig.js @@ -0,0 +1,11 @@ +deliveryClient + .items() + .type('article') + .equalsFilter('elements.url_pattern', articleSlug) + .queryConfig({ + urlSlugResolver: (link, context) => { + return resolveUrl(link); + }, + }) + .toPromise() + // Continue as above diff --git a/js/build-first-app/build_first_js_app_article_4_renderhash.js b/js/build-first-app/build_first_js_app_article_4_renderhash.js new file mode 100644 index 00000000..684f2ffe --- /dev/null +++ b/js/build-first-app/build_first_js_app_article_4_renderhash.js @@ -0,0 +1,5 @@ +// Reload page on hash change +const renderHash = () => { + window.history.go(); +}; +window.addEventListener('hashchange', renderHash, false); diff --git a/js/build-first-app/build_first_js_app_article_5_resolvevideo.js b/js/build-first-app/build_first_js_app_article_5_resolvevideo.js new file mode 100644 index 00000000..d11d1234 --- /dev/null +++ b/js/build-first-app/build_first_js_app_article_5_resolvevideo.js @@ -0,0 +1,30 @@ +const rteResolver = Kk.createRichTextHtmlResolver().resolveRichText({ + element: richTextElement, + linkedItems: Kk.linkedItemsHelper.convertLinkedItemsToArray(response.data.linkedItems), + urlResolver: (linkId, linkText, link) => { + // Your link resolution logic + }, + contentItemResolver: (itemId, item) => { + if (item.system.type === 'hosted_video') { + const videoID = item.elements.video_id.value; + + // Check if a video host exists + const videoHost = + item.elements.video_host.value && item.elements.video_host.value.length + ? item.elements.video_host.value[0].codename + : undefined; + if (videoHost) { + // Return based on hosting provider + const htmlCode = videoHost === 'youtube' + ? `` + : ``; + return { + contentItemHtml: htmlCode + }; + } + } + return { + contentItemHtml: '' + }; + } +}); diff --git a/js/build-first-app/build_first_js_app_article_6_queryconfig.js b/js/build-first-app/build_first_js_app_article_6_queryconfig.js new file mode 100644 index 00000000..3a2238a5 --- /dev/null +++ b/js/build-first-app/build_first_js_app_article_6_queryconfig.js @@ -0,0 +1,14 @@ +deliveryClient + .items() + .type('article') + .equalsFilter('elements.url_pattern', articleSlug) + .queryConfig({ + urlSlugResolver: (link, context) => { + return resolveUrl(link); + }, + richTextResolver: (item, context) => { + return resolveLinkedItems(item); + } + }) + .toPromise() + // Continue as above diff --git a/js/build-first-app/build_first_js_app_article_7_error.js b/js/build-first-app/build_first_js_app_article_7_error.js new file mode 100644 index 00000000..b0f31b26 --- /dev/null +++ b/js/build-first-app/build_first_js_app_article_7_error.js @@ -0,0 +1,19 @@ +deliveryClient + .items() + .type('article') + .equalsFilter('elements.url_pattern', articleSlug) + .toPromise() + .then(response => { + // Check if article found before adding + const article = + response.data.items && response.data.items.length ? response.data.items[0] : undefined; + + // 404 message if not found + if (!article) { + app.innerHTML = '

That article could not be found.

'; + return; + } + }) + .catch(err => { + reportErrors(err); + }); diff --git a/js/structure-in-rte/structure_in_rte_resolve_links_to_items.js b/js/structure-in-rte/structure_in_rte_resolve_links_to_items.js new file mode 100644 index 00000000..d2241708 --- /dev/null +++ b/js/structure-in-rte/structure_in_rte_resolve_links_to_items.js @@ -0,0 +1,33 @@ +const KontentDelivery = require('@kontent-ai/delivery-sdk'); + +// Initializes the Delivery client +const deliveryClient = KontentDelivery.createDeliveryClient({ + environmentId: '', +}); + +// Gets your content item +const response = await deliveryClient.item('my_article') + .toPromise(); + +// Stores the contents of the rich text element +const richTextElement = response.data.item.elements.body; + +// Note: The code below executes correctly in browser. To adjust the code for nodejs, see https://kontent.ai/learn/js-rte-nodejs +// Defines how to resolve the rich text element +const resolvedRichText = KontentDelivery.createRichTextHtmlResolver().resolveRichText({ + // Gives the resolver the contents of your rich text + element: richTextElement, + urlResolver: (linkId, linkText, link) => { + let url = '#unsupported-link-type'; + // Checks the content type of the linked content item + if (link.type === 'article') + url = `/articles/${link.urlSlug}`; + return { + linkHtml: `${url}`, + // You can also return a plain URL + linkUrl: url, + }; +}); + +// Gets the resolved HTML content of your rich text +const resolvedRichTextHtml = resolvedRichText.html; diff --git a/js/structure-in-rte/structure_in_rte_resolve_tweet.js b/js/structure-in-rte/structure_in_rte_resolve_tweet.js new file mode 100644 index 00000000..e034f04b --- /dev/null +++ b/js/structure-in-rte/structure_in_rte_resolve_tweet.js @@ -0,0 +1,38 @@ +const KontentDelivery = require('@kontent-ai/delivery-sdk'); + +// Initializes the Delivery client +const deliveryClient = KontentDelivery.createDeliveryClient({ + environmentId: '', +}); + +// Gets your content item +const response = await deliveryClient.item('my_article') + .toPromise(); + +// Stores the contents of the rich text element +const richTextElement = response.data.item.elements.body; + +// Note: The code below executes correctly in browser. To adjust the code for nodejs, see https://kontent.ai/learn/js-rte-nodejs +// Defines how to resolve the rich text element +const resolvedRichText = KontentDelivery.createRichTextHtmlResolver().resolveRichText({ + // Gives the resolver the contents of your rich text + element: richTextElement, + // Points the resolver to the content items and components that might be used in the rich text element + linkedItems: KontentDelivery.linkedItemsHelper.convertLinkedItemsToArray(response.data.linkedItems), + contentItemResolver: (contentItem) => { + // For tweet items and components, resolves to the following HTML markup + if (contentItem && contentItem.system.type === 'tweet') { + return { + contentItemHtml: `` + }; + } + + // For other type of items and components, resolves to an empty string + return { + contentItemHtml: `
Unsupported type ${contentItem.system.type}
` + }; + } +}); + +// Gets the resolved HTML content of your rich text +const resolvedRichTextHtml = resolvedRichText.html; diff --git a/ts/structure-in-rte/structure_in_rte_resolve_links_to_items.ts b/ts/structure-in-rte/structure_in_rte_resolve_links_to_items.ts new file mode 100644 index 00000000..de185ed7 --- /dev/null +++ b/ts/structure-in-rte/structure_in_rte_resolve_links_to_items.ts @@ -0,0 +1,40 @@ +// Tip: Find more about JS/TS SDKs at https://kontent.ai/learn/javascript +import { createRichTextHtmlResolver, Elements, createDeliveryClient, linkedItemsHelper, IContentItem } from '@kontent-ai/delivery-sdk'; + +// Initializes the Delivery client +const deliveryClient = createDeliveryClient({ + environmentId: '' +}); + +// Tip: Create strongly typed models according to https://kontent.ai/learn/strongly-typed-models +export type Article = IContentItem<{ + title: Elements.TextElement; + body: Elements.RichTextElement; +}>; + +// Gets your content item +const response = await deliveryClient.item
('my_article') + .toPromise(); + +// Stores the contents of the rich text element +const richTextElement = response.data.item.elements.body; + +// Note: The code below executes correctly in browser. To adjust the code for nodejs, see https://kontent.ai/learn/js-rte-nodejs +// Defines how to resolve the rich text element +const resolvedRichText = createRichTextHtmlResolver().resolveRichText({ + // Gives the resolver the contents of your rich text. + element: richTextElement, + urlResolver: (linkId, linkText, link) => { + let url = '#unsupported-link-type'; + // Checks the content type of the linked content item + if (link.type === 'article') + url = `/articles/${link.urlSlug}`; + return { + linkHtml: `${url}`, + // You can also return a plain URL + linkUrl: url, + }; + } +}); + +const resolvedHtml = resolvedRichText.html; diff --git a/ts/structure-in-rte/structure_in_rte_resolve_tweet.ts b/ts/structure-in-rte/structure_in_rte_resolve_tweet.ts new file mode 100644 index 00000000..6521d1c0 --- /dev/null +++ b/ts/structure-in-rte/structure_in_rte_resolve_tweet.ts @@ -0,0 +1,44 @@ +// Tip: Find more about JS/TS SDKs at https://kontent.ai/learn/javascript +import { createRichTextHtmlResolver, Elements, createDeliveryClient, linkedItemsHelper, IContentItem } from '@kontent-ai/delivery-sdk'; + +const deliveryClient = createDeliveryClient({ + environmentId: '' +}); + +// Tip: Create strongly typed models according to https://kontent.ai/learn/strongly-typed-models +export type Article = IContentItem<{ + title: Elements.TextElement; + body: Elements.RichTextElement; +}>; + +// Gets your content item with the rich text element +const response = await deliveryClient.item
('my_article') + .toPromise(); + +// Gets the contents of the rich text element +const richTextElement = response.data.item.elements.body; + +// Note: The code below executes correctly in browser. To adjust the code for nodejs, see https://kontent.ai/learn/js-rte-nodejs +// Defines how to resolve the rich text element +const resolvedRichText = createRichTextHtmlResolver().resolveRichText({ + // Gives the resolver the contents of your rich text + element: richTextElement, + // Points the resolver to the content items and components that might be used in the rich text element + linkedItems: linkedItemsHelper.convertLinkedItemsToArray(response.data.linkedItems), + contentItemResolver: (itemId, contentItem) => { + // For tweet items and components, resolves to the following HTML markup + if (contentItem && contentItem.system.type === 'tweet') { + return { + contentItemHtml: `` + }; + } + + // For other type of items and components, resolves to an empty string + return { + contentItemHtml: `
Unsupported type ${contentItem.system.type}
` + }; + } +}); + +// Gets the resolved HTML content of your rich text +const resolvedRichTextHtml = resolvedRichText.html; From 7cdb34a04fcdc8e54916f2551d3d459030b13d61 Mon Sep 17 00:00:00 2001 From: Jan Cerman Date: Tue, 24 Sep 2024 15:21:23 +0200 Subject: [PATCH 4/7] CTC-2582 Remove build first app in JS --- .../build_first_js_app_article.html | 30 ------------ ...uild_first_js_app_article_1_createnodes.js | 49 ------------------- ...ild_first_js_app_article_2_resolvelinks.js | 14 ------ ...uild_first_js_app_article_3_queryconfig.js | 11 ----- ...build_first_js_app_article_4_renderhash.js | 5 -- ...ild_first_js_app_article_5_resolvevideo.js | 30 ------------ ...uild_first_js_app_article_6_queryconfig.js | 14 ------ .../build_first_js_app_article_7_error.js | 19 ------- 8 files changed, 172 deletions(-) delete mode 100644 js/build-first-app/build_first_js_app_article.html delete mode 100644 js/build-first-app/build_first_js_app_article_1_createnodes.js delete mode 100644 js/build-first-app/build_first_js_app_article_2_resolvelinks.js delete mode 100644 js/build-first-app/build_first_js_app_article_3_queryconfig.js delete mode 100644 js/build-first-app/build_first_js_app_article_4_renderhash.js delete mode 100644 js/build-first-app/build_first_js_app_article_5_resolvevideo.js delete mode 100644 js/build-first-app/build_first_js_app_article_6_queryconfig.js delete mode 100644 js/build-first-app/build_first_js_app_article_7_error.js diff --git a/js/build-first-app/build_first_js_app_article.html b/js/build-first-app/build_first_js_app_article.html deleted file mode 100644 index 29bb186d..00000000 --- a/js/build-first-app/build_first_js_app_article.html +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - - Article - - - - - -
-

Articles

-
-
- - - - - - - - diff --git a/js/build-first-app/build_first_js_app_article_1_createnodes.js b/js/build-first-app/build_first_js_app_article_1_createnodes.js deleted file mode 100644 index e724f865..00000000 --- a/js/build-first-app/build_first_js_app_article_1_createnodes.js +++ /dev/null @@ -1,49 +0,0 @@ -// Define which article is being retrieved -const articleSlug = location.hash.slice(1); - -// Create article container -const articleContainer = addToElementbyId('div', 'article', app); - -// Call for article info -deliveryClient - .items() - .type('article') - .equalsFilter('elements.url_pattern', articleSlug) - .toPromise() - .then(response => { - // Check if article found before adding - const article = - response.data.items && response.data.items.length ? response.data.items[0] : undefined; - - // Update title - document.title = `Article | ${article.system.name}`; - - // Create nodes - const headerImage = createElement( - 'img', - 'article-header', - 'src', - article.elements.teaser_image.value[0].url - ); - const title = createElement( - 'h2', - 'article-title', - 'innerText', - article.elements.title.value - ); - const richTextElement = article.elements.body_copy; - const rteResolver = Kk.createRichTextHtmlResolver().resolveRichText({ - element: richTextElement, - // Here you'll define your resolvers - }); - const body = createElement( - 'div', - 'article-description', - 'innerHTML', - rteResolver.html - ); - - // Add nodes to DOM - articleContainer.append(headerImage, title, body); - return; - }); diff --git a/js/build-first-app/build_first_js_app_article_2_resolvelinks.js b/js/build-first-app/build_first_js_app_article_2_resolvelinks.js deleted file mode 100644 index c01d7c64..00000000 --- a/js/build-first-app/build_first_js_app_article_2_resolvelinks.js +++ /dev/null @@ -1,14 +0,0 @@ -const rteResolver = Kk.createRichTextHtmlResolver().resolveRichText({ - element: richTextElement, - linkedItems: Kk.linkedItemsHelper.convertLinkedItemsToArray(response.data.linkedItems), - urlResolver: (linkId, linkText, link) => { - // Set link based on type - const urlLocation = - link.type === 'article' - ? `article.html#${link.urlSlug}` - : link.type === 'coffee' - ? `coffee.html#${link.urlSlug}` - : 'unsupported-link'; - return { linkUrl: urlLocation }; - }, -}); diff --git a/js/build-first-app/build_first_js_app_article_3_queryconfig.js b/js/build-first-app/build_first_js_app_article_3_queryconfig.js deleted file mode 100644 index 9111637c..00000000 --- a/js/build-first-app/build_first_js_app_article_3_queryconfig.js +++ /dev/null @@ -1,11 +0,0 @@ -deliveryClient - .items() - .type('article') - .equalsFilter('elements.url_pattern', articleSlug) - .queryConfig({ - urlSlugResolver: (link, context) => { - return resolveUrl(link); - }, - }) - .toPromise() - // Continue as above diff --git a/js/build-first-app/build_first_js_app_article_4_renderhash.js b/js/build-first-app/build_first_js_app_article_4_renderhash.js deleted file mode 100644 index 684f2ffe..00000000 --- a/js/build-first-app/build_first_js_app_article_4_renderhash.js +++ /dev/null @@ -1,5 +0,0 @@ -// Reload page on hash change -const renderHash = () => { - window.history.go(); -}; -window.addEventListener('hashchange', renderHash, false); diff --git a/js/build-first-app/build_first_js_app_article_5_resolvevideo.js b/js/build-first-app/build_first_js_app_article_5_resolvevideo.js deleted file mode 100644 index d11d1234..00000000 --- a/js/build-first-app/build_first_js_app_article_5_resolvevideo.js +++ /dev/null @@ -1,30 +0,0 @@ -const rteResolver = Kk.createRichTextHtmlResolver().resolveRichText({ - element: richTextElement, - linkedItems: Kk.linkedItemsHelper.convertLinkedItemsToArray(response.data.linkedItems), - urlResolver: (linkId, linkText, link) => { - // Your link resolution logic - }, - contentItemResolver: (itemId, item) => { - if (item.system.type === 'hosted_video') { - const videoID = item.elements.video_id.value; - - // Check if a video host exists - const videoHost = - item.elements.video_host.value && item.elements.video_host.value.length - ? item.elements.video_host.value[0].codename - : undefined; - if (videoHost) { - // Return based on hosting provider - const htmlCode = videoHost === 'youtube' - ? `` - : ``; - return { - contentItemHtml: htmlCode - }; - } - } - return { - contentItemHtml: '' - }; - } -}); diff --git a/js/build-first-app/build_first_js_app_article_6_queryconfig.js b/js/build-first-app/build_first_js_app_article_6_queryconfig.js deleted file mode 100644 index 3a2238a5..00000000 --- a/js/build-first-app/build_first_js_app_article_6_queryconfig.js +++ /dev/null @@ -1,14 +0,0 @@ -deliveryClient - .items() - .type('article') - .equalsFilter('elements.url_pattern', articleSlug) - .queryConfig({ - urlSlugResolver: (link, context) => { - return resolveUrl(link); - }, - richTextResolver: (item, context) => { - return resolveLinkedItems(item); - } - }) - .toPromise() - // Continue as above diff --git a/js/build-first-app/build_first_js_app_article_7_error.js b/js/build-first-app/build_first_js_app_article_7_error.js deleted file mode 100644 index b0f31b26..00000000 --- a/js/build-first-app/build_first_js_app_article_7_error.js +++ /dev/null @@ -1,19 +0,0 @@ -deliveryClient - .items() - .type('article') - .equalsFilter('elements.url_pattern', articleSlug) - .toPromise() - .then(response => { - // Check if article found before adding - const article = - response.data.items && response.data.items.length ? response.data.items[0] : undefined; - - // 404 message if not found - if (!article) { - app.innerHTML = '

That article could not be found.

'; - return; - } - }) - .catch(err => { - reportErrors(err); - }); From e1b8d3601b2aa0c2316251cb699202582a3dd0b2 Mon Sep 17 00:00:00 2001 From: Jan Cerman Date: Tue, 24 Sep 2024 16:44:30 +0200 Subject: [PATCH 5/7] CTC-2582 Remove rte resolution examples in JS --- ...structure_in_rte_resolve_links_to_items.js | 33 -------- .../structure_in_rte_resolve_tweet.js | 38 --------- ...ructure_in_rte_use_standalone_resolver.jsx | 84 ------------------- 3 files changed, 155 deletions(-) delete mode 100644 js/structure-in-rte/structure_in_rte_resolve_links_to_items.js delete mode 100644 js/structure-in-rte/structure_in_rte_resolve_tweet.js delete mode 100644 js/structure-in-rte/structure_in_rte_use_standalone_resolver.jsx diff --git a/js/structure-in-rte/structure_in_rte_resolve_links_to_items.js b/js/structure-in-rte/structure_in_rte_resolve_links_to_items.js deleted file mode 100644 index d2241708..00000000 --- a/js/structure-in-rte/structure_in_rte_resolve_links_to_items.js +++ /dev/null @@ -1,33 +0,0 @@ -const KontentDelivery = require('@kontent-ai/delivery-sdk'); - -// Initializes the Delivery client -const deliveryClient = KontentDelivery.createDeliveryClient({ - environmentId: '', -}); - -// Gets your content item -const response = await deliveryClient.item('my_article') - .toPromise(); - -// Stores the contents of the rich text element -const richTextElement = response.data.item.elements.body; - -// Note: The code below executes correctly in browser. To adjust the code for nodejs, see https://kontent.ai/learn/js-rte-nodejs -// Defines how to resolve the rich text element -const resolvedRichText = KontentDelivery.createRichTextHtmlResolver().resolveRichText({ - // Gives the resolver the contents of your rich text - element: richTextElement, - urlResolver: (linkId, linkText, link) => { - let url = '#unsupported-link-type'; - // Checks the content type of the linked content item - if (link.type === 'article') - url = `/articles/${link.urlSlug}`; - return { - linkHtml: `${url}`, - // You can also return a plain URL - linkUrl: url, - }; -}); - -// Gets the resolved HTML content of your rich text -const resolvedRichTextHtml = resolvedRichText.html; diff --git a/js/structure-in-rte/structure_in_rte_resolve_tweet.js b/js/structure-in-rte/structure_in_rte_resolve_tweet.js deleted file mode 100644 index e034f04b..00000000 --- a/js/structure-in-rte/structure_in_rte_resolve_tweet.js +++ /dev/null @@ -1,38 +0,0 @@ -const KontentDelivery = require('@kontent-ai/delivery-sdk'); - -// Initializes the Delivery client -const deliveryClient = KontentDelivery.createDeliveryClient({ - environmentId: '', -}); - -// Gets your content item -const response = await deliveryClient.item('my_article') - .toPromise(); - -// Stores the contents of the rich text element -const richTextElement = response.data.item.elements.body; - -// Note: The code below executes correctly in browser. To adjust the code for nodejs, see https://kontent.ai/learn/js-rte-nodejs -// Defines how to resolve the rich text element -const resolvedRichText = KontentDelivery.createRichTextHtmlResolver().resolveRichText({ - // Gives the resolver the contents of your rich text - element: richTextElement, - // Points the resolver to the content items and components that might be used in the rich text element - linkedItems: KontentDelivery.linkedItemsHelper.convertLinkedItemsToArray(response.data.linkedItems), - contentItemResolver: (contentItem) => { - // For tweet items and components, resolves to the following HTML markup - if (contentItem && contentItem.system.type === 'tweet') { - return { - contentItemHtml: `` - }; - } - - // For other type of items and components, resolves to an empty string - return { - contentItemHtml: `
Unsupported type ${contentItem.system.type}
` - }; - } -}); - -// Gets the resolved HTML content of your rich text -const resolvedRichTextHtml = resolvedRichText.html; diff --git a/js/structure-in-rte/structure_in_rte_use_standalone_resolver.jsx b/js/structure-in-rte/structure_in_rte_use_standalone_resolver.jsx deleted file mode 100644 index 266650f5..00000000 --- a/js/structure-in-rte/structure_in_rte_use_standalone_resolver.jsx +++ /dev/null @@ -1,84 +0,0 @@ -import React from "react"; -import { PortableText, 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"; - -const richTextElement = {/* rich text element from SDK response */} - -/** - * object, defining resolution for various portable text objects. - * to be passed into component. - */ -const portableTextComponents = { - types: { - // resolution for component custom block, representing linked items/components in rich text content - component: ({ value }) => { - 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 }) => { - 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 }) => { - const imageString = resolveImage(value, toHTMLImageDefault); - return <>{imageString}; - } - }, - marks: { - // resolution for links to external URLs - link: ({ value, children }) => { - const target = (value?.href || '').startsWith('http') ? '_blank' : undefined - return ( - - {children} - - ) - }, - // resolution for links to content items - internalLink: ({ value, children }) => { - 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 }) => ( -

- {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 From 289363d6abe06197284c2423f5783cc2d96db616 Mon Sep 17 00:00:00 2001 From: Jan Cerman Date: Fri, 4 Oct 2024 17:22:25 +0200 Subject: [PATCH 6/7] CTC-2582 Add rich text resolver samples --- .../resolve_rich_text_components_items.ts | 35 +++++++++++++++ ts/structure-in-rte/resolve_rich_text_flow.ts | 35 +++++++++++++++ .../resolve_rich_text_links_to_items.ts | 26 +++++++++++ ...structure_in_rte_resolve_links_to_items.ts | 40 ----------------- .../structure_in_rte_resolve_tweet.ts | 44 ------------------- 5 files changed, 96 insertions(+), 84 deletions(-) create mode 100644 ts/structure-in-rte/resolve_rich_text_components_items.ts create mode 100644 ts/structure-in-rte/resolve_rich_text_flow.ts create mode 100644 ts/structure-in-rte/resolve_rich_text_links_to_items.ts delete mode 100644 ts/structure-in-rte/structure_in_rte_resolve_links_to_items.ts delete mode 100644 ts/structure-in-rte/structure_in_rte_resolve_tweet.ts diff --git a/ts/structure-in-rte/resolve_rich_text_components_items.ts b/ts/structure-in-rte/resolve_rich_text_components_items.ts new file mode 100644 index 00000000..275a8023 --- /dev/null +++ b/ts/structure-in-rte/resolve_rich_text_components_items.ts @@ -0,0 +1,35 @@ +import { PortableTextComponent, PortableTextReactComponents, PortableTextTypeComponentProps } from "@portabletext/react"; + +// Defines how to transform Kontent.ai-specific portable text components +const portableTextComponents: Partial = { + // The specific logic for each component is explained later in the lesson + types: { + component: ({ + value, + }: PortableTextTypeComponentProps) => { + // TODO: Specify where 'element' comes from + const componentOrItem = element.linkedItems.find( + (i) => i.system.codename === value.component._ref + ); + + if (!componentOrItem) { + throw new Error( + "Content item wasn't found. Check your request depth." + ); + } + + // Renders specific React components based on the content type + switch (componentOrItem.system.type) { + // Check https://kontent.ai/learn/strongly-typed-models to create content type models + case contentTypes.callout.codename: + return ; + case contentTypes.action.codename: + return ; + case contentTypes.content_chunk.codename: + return ; + default: + return `Unsupported content type "${componentItem.system.type}"` + } + } + } +} \ No newline at end of file diff --git a/ts/structure-in-rte/resolve_rich_text_flow.ts b/ts/structure-in-rte/resolve_rich_text_flow.ts new file mode 100644 index 00000000..1e45551b --- /dev/null +++ b/ts/structure-in-rte/resolve_rich_text_flow.ts @@ -0,0 +1,35 @@ +import { Elements } from '@kontent-ai/delivery-sdk'; +import { nodeParse, transformToPortableText } from "@kontent-ai/rich-text-resolver" +import { PortableText, PortableTextReactComponents } from "@portabletext/react"; + +// Defines how to transform Kontent.ai-specific portable text components +const portableTextComponents: Partial = { + // The logic for each portable text component is explained later in the lesson + types: { + component: {}, // Components in rich text + table: {}, // Tables in rich text + image: {} // Assets in rich text + }, + marks: { + link: {}, // Links to external URLs + internalLink: {} // Links to content items + }, +} + +// Custom React component that renders your rich text element +const MyComponent = ({ value }: Elements.RichTextElement) => { + // Converts Kontent.ai rich text HTML to a JSON tree + const parsedTree = nodeParse(value); + // Converts the JSON tree to portable text + const portableText = transformToPortableText(parsedTree); + // Renders portable text based on the specified portable text component transformations + return ; +}; + +// In your application code, get a content item and retrieve its rich text element. +// Get familiar with retrieving content in https://kontent.ai/learn/develop/hello-world +const richTextElement: Elements.RichTextElement = response.data.item.elements.richtext; +// 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.ts b/ts/structure-in-rte/resolve_rich_text_links_to_items.ts new file mode 100644 index 00000000..954dea69 --- /dev/null +++ b/ts/structure-in-rte/resolve_rich_text_links_to_items.ts @@ -0,0 +1,26 @@ +import { PortableTextMarkComponentProps, PortableTextReactComponents } from "@portabletext/react"; +import {IPortableTextInternalLink} from "@kontent-ai/rich-text-resolver"; + +// Defines how to transform Kontent.ai-specific portable text components +const portableTextComponents: Partial = { + marks: { + // TODO: Explain where 'value' and 'children' come from when the transformation happens + internalLink: ({ + value, + children, + // TODO: Resolve "@kontent-ai/rich-text-resolver"' has no exported member named 'IPortableTextInternalLink'? + }: PortableTextMarkComponentProps) => { + // TODO: Explain where 'element' comes from + const link = element.links.find( + (l) => l.linkId === value?.reference._ref + ); + if (!link) { + throw new Error( + "Cannot find link reference in links. This should never happen." + ); + } + // TODO: Show what 'InternalLink' does + return {children}; + }, + } +} \ No newline at end of file diff --git a/ts/structure-in-rte/structure_in_rte_resolve_links_to_items.ts b/ts/structure-in-rte/structure_in_rte_resolve_links_to_items.ts deleted file mode 100644 index de185ed7..00000000 --- a/ts/structure-in-rte/structure_in_rte_resolve_links_to_items.ts +++ /dev/null @@ -1,40 +0,0 @@ -// Tip: Find more about JS/TS SDKs at https://kontent.ai/learn/javascript -import { createRichTextHtmlResolver, Elements, createDeliveryClient, linkedItemsHelper, IContentItem } from '@kontent-ai/delivery-sdk'; - -// Initializes the Delivery client -const deliveryClient = createDeliveryClient({ - environmentId: '' -}); - -// Tip: Create strongly typed models according to https://kontent.ai/learn/strongly-typed-models -export type Article = IContentItem<{ - title: Elements.TextElement; - body: Elements.RichTextElement; -}>; - -// Gets your content item -const response = await deliveryClient.item
('my_article') - .toPromise(); - -// Stores the contents of the rich text element -const richTextElement = response.data.item.elements.body; - -// Note: The code below executes correctly in browser. To adjust the code for nodejs, see https://kontent.ai/learn/js-rte-nodejs -// Defines how to resolve the rich text element -const resolvedRichText = createRichTextHtmlResolver().resolveRichText({ - // Gives the resolver the contents of your rich text. - element: richTextElement, - urlResolver: (linkId, linkText, link) => { - let url = '#unsupported-link-type'; - // Checks the content type of the linked content item - if (link.type === 'article') - url = `/articles/${link.urlSlug}`; - return { - linkHtml: `${url}`, - // You can also return a plain URL - linkUrl: url, - }; - } -}); - -const resolvedHtml = resolvedRichText.html; diff --git a/ts/structure-in-rte/structure_in_rte_resolve_tweet.ts b/ts/structure-in-rte/structure_in_rte_resolve_tweet.ts deleted file mode 100644 index 6521d1c0..00000000 --- a/ts/structure-in-rte/structure_in_rte_resolve_tweet.ts +++ /dev/null @@ -1,44 +0,0 @@ -// Tip: Find more about JS/TS SDKs at https://kontent.ai/learn/javascript -import { createRichTextHtmlResolver, Elements, createDeliveryClient, linkedItemsHelper, IContentItem } from '@kontent-ai/delivery-sdk'; - -const deliveryClient = createDeliveryClient({ - environmentId: '' -}); - -// Tip: Create strongly typed models according to https://kontent.ai/learn/strongly-typed-models -export type Article = IContentItem<{ - title: Elements.TextElement; - body: Elements.RichTextElement; -}>; - -// Gets your content item with the rich text element -const response = await deliveryClient.item
('my_article') - .toPromise(); - -// Gets the contents of the rich text element -const richTextElement = response.data.item.elements.body; - -// Note: The code below executes correctly in browser. To adjust the code for nodejs, see https://kontent.ai/learn/js-rte-nodejs -// Defines how to resolve the rich text element -const resolvedRichText = createRichTextHtmlResolver().resolveRichText({ - // Gives the resolver the contents of your rich text - element: richTextElement, - // Points the resolver to the content items and components that might be used in the rich text element - linkedItems: linkedItemsHelper.convertLinkedItemsToArray(response.data.linkedItems), - contentItemResolver: (itemId, contentItem) => { - // For tweet items and components, resolves to the following HTML markup - if (contentItem && contentItem.system.type === 'tweet') { - return { - contentItemHtml: `` - }; - } - - // For other type of items and components, resolves to an empty string - return { - contentItemHtml: `
Unsupported type ${contentItem.system.type}
` - }; - } -}); - -// Gets the resolved HTML content of your rich text -const resolvedRichTextHtml = resolvedRichText.html; From 6528dbe85607f8f4b4fd1fd3a84422a94465510d Mon Sep 17 00:00:00 2001 From: Daniel Pokorny <52500882+pokornyd@users.noreply.github.com> Date: Wed, 23 Oct 2024 16:48:00 +0200 Subject: [PATCH 7/7] CTC-2582 update portable text examples (#90) * CTC-2582 update portable text examples * CTC-2582 Extend rich text resolver samples Added comments and changed return values --------- Co-authored-by: Jan Cerman --- .../resolve_rich_text_components_items.ts | 35 -------- .../resolve_rich_text_components_items.tsx | 35 ++++++++ ts/structure-in-rte/resolve_rich_text_flow.ts | 35 -------- .../resolve_rich_text_flow.tsx | 55 ++++++++++++ .../resolve_rich_text_links_to_items.ts | 26 ------ .../resolve_rich_text_links_to_items.tsx | 52 +++++++++++ ...ructure_in_rte_use_standalone_resolver.tsx | 86 ------------------- 7 files changed, 142 insertions(+), 182 deletions(-) delete mode 100644 ts/structure-in-rte/resolve_rich_text_components_items.ts create mode 100644 ts/structure-in-rte/resolve_rich_text_components_items.tsx delete mode 100644 ts/structure-in-rte/resolve_rich_text_flow.ts create mode 100644 ts/structure-in-rte/resolve_rich_text_flow.tsx delete mode 100644 ts/structure-in-rte/resolve_rich_text_links_to_items.ts create mode 100644 ts/structure-in-rte/resolve_rich_text_links_to_items.tsx delete mode 100644 ts/structure-in-rte/structure_in_rte_use_standalone_resolver.tsx diff --git a/ts/structure-in-rte/resolve_rich_text_components_items.ts b/ts/structure-in-rte/resolve_rich_text_components_items.ts deleted file mode 100644 index 275a8023..00000000 --- a/ts/structure-in-rte/resolve_rich_text_components_items.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { PortableTextComponent, PortableTextReactComponents, PortableTextTypeComponentProps } from "@portabletext/react"; - -// Defines how to transform Kontent.ai-specific portable text components -const portableTextComponents: Partial = { - // The specific logic for each component is explained later in the lesson - types: { - component: ({ - value, - }: PortableTextTypeComponentProps) => { - // TODO: Specify where 'element' comes from - const componentOrItem = element.linkedItems.find( - (i) => i.system.codename === value.component._ref - ); - - if (!componentOrItem) { - throw new Error( - "Content item wasn't found. Check your request depth." - ); - } - - // Renders specific React components based on the content type - switch (componentOrItem.system.type) { - // Check https://kontent.ai/learn/strongly-typed-models to create content type models - case contentTypes.callout.codename: - return ; - case contentTypes.action.codename: - return ; - case contentTypes.content_chunk.codename: - return ; - default: - return `Unsupported content type "${componentItem.system.type}"` - } - } - } -} \ No newline at end of file diff --git a/ts/structure-in-rte/resolve_rich_text_components_items.tsx b/ts/structure-in-rte/resolve_rich_text_components_items.tsx new file mode 100644 index 00000000..bccacd19 --- /dev/null +++ b/ts/structure-in-rte/resolve_rich_text_components_items.tsx @@ -0,0 +1,35 @@ +import { Elements } from "@kontent-ai/delivery-sdk"; +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"; + +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) { + 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 (
Content based on the type '{componentOrItem.system.type}' couldn't be resolved.
); + } + }, + }, +}); \ No newline at end of file diff --git a/ts/structure-in-rte/resolve_rich_text_flow.ts b/ts/structure-in-rte/resolve_rich_text_flow.ts deleted file mode 100644 index 1e45551b..00000000 --- a/ts/structure-in-rte/resolve_rich_text_flow.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { Elements } from '@kontent-ai/delivery-sdk'; -import { nodeParse, transformToPortableText } from "@kontent-ai/rich-text-resolver" -import { PortableText, PortableTextReactComponents } from "@portabletext/react"; - -// Defines how to transform Kontent.ai-specific portable text components -const portableTextComponents: Partial = { - // The logic for each portable text component is explained later in the lesson - types: { - component: {}, // Components in rich text - table: {}, // Tables in rich text - image: {} // Assets in rich text - }, - marks: { - link: {}, // Links to external URLs - internalLink: {} // Links to content items - }, -} - -// Custom React component that renders your rich text element -const MyComponent = ({ value }: Elements.RichTextElement) => { - // Converts Kontent.ai rich text HTML to a JSON tree - const parsedTree = nodeParse(value); - // Converts the JSON tree to portable text - const portableText = transformToPortableText(parsedTree); - // Renders portable text based on the specified portable text component transformations - return ; -}; - -// In your application code, get a content item and retrieve its rich text element. -// Get familiar with retrieving content in https://kontent.ai/learn/develop/hello-world -const richTextElement: Elements.RichTextElement = response.data.item.elements.richtext; -// 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_flow.tsx b/ts/structure-in-rte/resolve_rich_text_flow.tsx new file mode 100644 index 00000000..f92ee172 --- /dev/null +++ b/ts/structure-in-rte/resolve_rich_text_flow.tsx @@ -0,0 +1,55 @@ +import { Elements } from "@kontent-ai/delivery-sdk"; +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 createRichTextResolver = (element: Elements.RichTextElement): Partial => ({ + // The logic for individual portable text components is explained later in the lesson + types: { + // 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: { + // Resolution for links to external URLs + link: undefined, + // Resolution for links to content items + internalLink: undefined, + }, + block: { + // 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 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 content based on the specified transformations + return ( + + ); +}; + +// In your application code, get a content item and retrieve its rich text element. +// Get familiar with retrieving content in https://kontent.ai/learn/develop/hello-world +// const richTextElement: Elements.RichTextElement = response.data.item.elements.richtext; +// 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.ts b/ts/structure-in-rte/resolve_rich_text_links_to_items.ts deleted file mode 100644 index 954dea69..00000000 --- a/ts/structure-in-rte/resolve_rich_text_links_to_items.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { PortableTextMarkComponentProps, PortableTextReactComponents } from "@portabletext/react"; -import {IPortableTextInternalLink} from "@kontent-ai/rich-text-resolver"; - -// Defines how to transform Kontent.ai-specific portable text components -const portableTextComponents: Partial = { - marks: { - // TODO: Explain where 'value' and 'children' come from when the transformation happens - internalLink: ({ - value, - children, - // TODO: Resolve "@kontent-ai/rich-text-resolver"' has no exported member named 'IPortableTextInternalLink'? - }: PortableTextMarkComponentProps) => { - // TODO: Explain where 'element' comes from - const link = element.links.find( - (l) => l.linkId === value?.reference._ref - ); - if (!link) { - throw new Error( - "Cannot find link reference in links. This should never happen." - ); - } - // TODO: Show what 'InternalLink' does - return {children}; - }, - } -} \ 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 new file mode 100644 index 00000000..3d667878 --- /dev/null +++ b/ts/structure-in-rte/resolve_rich_text_links_to_items.tsx @@ -0,0 +1,52 @@ +import { Elements, ILink } from "@kontent-ai/delivery-sdk"; +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 ContentItemLinkProps = { + link: ILink; + children: ReactNode; +}; + +// 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 ( + + {props.children} + + ); + default: + return (
Link to the content item '{props.link.codename}' couldn't be resolved.
); + } +}; + +type ProductLinkProps = {}; +const ProductLink: React.FC = (props) => { + // 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