Aggiungere widget all’editor Rich Text
Scopri come aggiungere widget all’Editor Rich Text nell’Editor frammenti di contenuto AEM.
Per aggiungere contenuto dinamico nell'editor Rich Text, è possibile utilizzare la funzionalità widget. I widget consentono di integrare l’interfaccia utente semplice o complessa nell’editor Rich Text e l’interfaccia utente tramite il framework JS scelto. Possono essere considerate finestre di dialogo aperte premendo il tasto speciale {
nell'editor Rich Text.
In genere, i widget vengono utilizzati per inserire il contenuto dinamico che ha una dipendenza di sistema esterna o che potrebbe cambiare in base al contesto corrente.
I widget vengono aggiunti all'editor RTE nell'editor frammenti di contenuto utilizzando il punto di estensione rte
. Utilizzando il metodo getWidgets()
del punto di estensione rte
, vengono aggiunti uno o più widget. Vengono attivati premendo il tasto speciale {
per aprire l'opzione del menu di scelta rapida, quindi selezionare il widget desiderato per caricare l'interfaccia utente della finestra di dialogo personalizzata.
In questo esempio viene illustrato come aggiungere un widget denominato Elenco codici sconto per trovare, selezionare e aggiungere il codice sconto WKND specifico dell'avventura all'interno di un contenuto RTE. Questi codici di sconto possono essere gestiti in sistemi esterni come Order Management System (OMS), Product Information Management (PIM), applicazioni sviluppate in casa o un'azione AppBuilder di Adobe.
Per semplificare, in questo esempio viene utilizzato il framework Adobe React Spectrum per sviluppare l'interfaccia utente del widget o della finestra di dialogo e il nome dell'avventura WKND hardcoded e i dati del codice sconto.
Punto di estensione
Questo esempio si estende fino al punto di estensione rte
per aggiungere un widget all'editor Rich Text nell'Editor frammenti di contenuto.
Estensione di esempio
Nell'esempio seguente viene creato un widget Elenco codici sconto. Premendo il tasto speciale {
nell'editor Rich Text, viene aperto il menu di scelta rapida, quindi selezionando l'opzione Elenco codici sconto dal menu di scelta rapida viene aperta la finestra di dialogo.
Gli autori di contenuti WKND possono trovare, selezionare e aggiungere il codice di sconto corrente specifico per Adventure, se disponibile.
Registrazione dell’estensione
ExtensionRegistration.js
, mappato alla route index.html, è il punto di ingresso per l'estensione AEM e definisce:
- Definizione del widget nella funzione
getWidgets()
con attributiid, label and url
. - Il valore dell'attributo
url
, un percorso URL relativo (/index.html#/discountCodes
) per caricare l'interfaccia utente della finestra di dialogo.
src/aem-cf-editor-1/web-src/src/components/ExtensionRegistration.js
import React from "react";
import { Text } from "@adobe/react-spectrum";
import { register } from "@adobe/uix-guest";
import { extensionId } from "./Constants";
// This function is called when the extension is registered with the host and runs in an iframe in the Content Fragment Editor browser window.
function ExtensionRegistration() {
const init = async () => {
const guestConnection = await register({
id: extensionId,
methods: {
rte: {
// RTE Widgets
getWidgets: () => [
{
id: "discountcode-list-widget", // Provide a unique ID for the widget
label: "Discount Code List", // Provide a label for the widget
url: "/index.html#/discountCodes", // Provide the "relative" URL to the widget content. It will be resolved as `/index.html#/discountCodes`
},
],
}, // Add a comma here
},
});
};
init().catch(console.error);
return <Text>IFrame for integration with Host (AEM)...</Text>;
}
export default ExtensionRegistration;
Aggiungi route discountCodes
in App.js
Nel componente React principale App.js
, aggiungi la route discountCodes
per eseguire il rendering dell'interfaccia utente per il percorso URL relativo sopra indicato.
src/aem-cf-editor-1/web-src/src/components/App.js
...
<Routes>
<Route index element={<ExtensionRegistration />} />
<Route
exact path="index.html"
element={<ExtensionRegistration />}
/>
{/* Content Fragment RTE routes that support the Discount Codes Widget functionality*/}
<Route path="/discountCodes" element={<DiscountCodes />} />
</Routes>
...
Crea componente React DiscountCodes
L'interfaccia utente del widget o della finestra di dialogo viene creata utilizzando il framework Adobe React Spectrum. Di seguito è riportato il codice del componente DiscountCodes
, con le evidenziazioni chiave:
- Il rendering dell'interfaccia utente viene eseguito utilizzando i componenti Spectrum di React, ad esempio ComboBox, ButtonGroup, Button
- L'array
adventureDiscountCodes
dispone della mappatura hardcoded del nome dell'avventura e del codice sconto. In uno scenario reale, questi dati possono essere recuperati da un’azione Adobe AppBuilder o da sistemi esterni come PIM, OMS o gateway API basato su provider cloud o home-based. guestConnection
è inizializzato con l'hookuseEffect
React ed è gestito come stato del componente. Viene utilizzato per comunicare con l’ospite dell’AEM.- La funzione
handleDiscountCodeChange
ottiene il codice sconto per il nome dell'avventura selezionato e aggiorna la variabile di stato. - La funzione
addDiscountCode
che utilizza l'oggettoguestConnection
fornisce istruzioni RTE da eseguire. In questo casoinsertContent
istruzione e frammento di codice HTML del codice sconto effettivo da inserire nell'editor Rich Text.
src/aem-cf-editor-1/web-src/src/components/DiscountCodes.js
import {
Button,
ButtonGroup,
ComboBox,
Content,
Divider,
Flex, Form,
Item,
Provider,
Text,
defaultTheme
} from '@adobe/react-spectrum';
import { attach } from '@adobe/uix-guest';
import React, { useEffect, useState } from 'react';
import { extensionId } from './Constants';
const DiscountCodes = () => {
// The Adventure Discount Code list
// In this example its hard coded, however you can call an Adobe AppBuilder Action or even make an AJAX call to load it from 3rd party system
const adventureDiscountCodes = [
{ id: 1, adventureName: 'BALI SURF CAMP', discountCode: 'BALI2023' },
{ id: 2, adventureName: 'BEERVANA IN PORTLAND', discountCode: 'PORTFEST' },
{ id: 3, adventureName: 'NAPA WINE TASTING', discountCode: 'WINEINSPRING' },
{ id: 4, adventureName: 'RIVERSIDE CAMPING', discountCode: 'SUMMERSCAPE' },
{ id: 5, adventureName: 'TAHOE SKIING', discountCode: 'EPICPASS' },
];
// Set up state used by the React component
const [guestConnection, setGuestConnection] = useState();
// State hooks to manage the component state
const [discountCode, setDiscountCode] = useState(null);
// Asynchronously attach the extension to AEM, we must wait or the guestConnection to be set before doing anything in the modal
useEffect(() => {
(async () => {
const myGuestConnection = await attach({ id: extensionId });
setGuestConnection(myGuestConnection);
})();
}, []);
// Handle the `discountCodeList` Dropdown change
const handleDiscountCodeChange = (key) => {
if (key) {
//console.log(`DiscountCode Key: ${key}`);
//console.log(`DiscountCode Value: ${adventureDiscountCodes[key-1].discountCode}`);
//Get discount code value using selected key/index
let discountCodeValue = adventureDiscountCodes[key - 1].discountCode;
//update the `discountCode` state
setDiscountCode(discountCodeValue);
}
};
// Add the selected Adventure's Discount Code into the RTE
const addDiscountCode = () => {
if (discountCode) {
// Use `guestConnection.host.rte.applyInstructions` method and provide RTE instruction to execute.
// The instructions are passed as an array of object, that has `type` and `value` keys
guestConnection.host.rte.applyInstructions([{ type: "insertContent", value: `<strong>Discount Code: ${discountCode}</strong>` }]);
}
};
// Adobe React Spectrum (HTML code) that renders the Discount Code dropdown list, see https://react-spectrum.adobe.com/react-spectrum/index.html
return (
<Provider theme={defaultTheme}>
<Content width="100%">
<Flex width="100%">
<Form width="50%">
<Text>Selected Discount Code: <strong>{discountCode}</strong></Text>
<p />
<Divider size="M" />
<ComboBox
name="discountCodeList"
label="Type or Select an Adventure name"
defaultItems={adventureDiscountCodes}
onSelectionChange={handleDiscountCodeChange}>
{item => <Item>{item.adventureName}</Item>}
</ComboBox>
<p />
<ButtonGroup align="right">
<Button variant="accent" onPress={addDiscountCode} autoFocus>Add</Button>
<Button variant="secondary" onPress={() => setDiscountCode(null)}>Clear</Button>
</ButtonGroup>
</Form>
</Flex>
</Content>
</Provider>
);
}
export default DiscountCodes;