Ajouter des badges à l’éditeur de texte enrichi (RTE)
Découvrez comment ajouter des badges à l’éditeur de texte enrichi (RTE) dans l’éditeur de fragment de contenu AEM.
Les badges de l’éditeur de texte enrichi sont des extensions qui rendent le texte de l’éditeur de texte enrichi (RTE) non modifiable. Cela signifie qu’un badge déclaré comme tel ne peut être que complètement supprimé et ne peut pas être partiellement modifié. Ces badges prennent également en charge les couleurs spéciales dans le RTE, indiquant clairement aux personnes qui créent le contenu que le texte est un badge et qu’il n’est donc pas modifiable. De plus, ils fournissent des indices visuels sur la signification du texte du badge.
Le cas d’utilisation le plus courant pour les badges RTE consiste à les utiliser conjointement avec les widgets RTE. Cela permet au contenu inséré dans l’éditeur de texte enrichi par le widget RTE d’être non modifiable.
En règle générale, les badges associés aux widgets sont utilisés pour ajouter le contenu dynamique avec une dépendance système externe, mais les personnes qui créent le contenu ne peuvent pas modifier le contenu dynamique inséré pour préserver l’intégrité. Ils ne peuvent être supprimés que dans leur ensemble.
Les badges sont ajoutés au RTE dans l’éditeur de fragment de contenu à l’aide du point d’extension rte
. La méthode rte
du point d’extension getBadges()
permet d’ajouter un ou plusieurs badges.
Cet exemple montre comment ajouter un widget appelé Service clientèle des réservations pour grands groupes pour rechercher, sélectionner et ajouter les informations du service clientèle spécifiques à l’aventure WKND, telles que le nom du représentant ou de la représentante et le numéro de téléphone dans un contenu d’éditeur de texte enrichi. L’utilisation de la fonctionnalité des badges permet de rendre le numéro de téléphone non modifiable, mais les personnes qui créent le contenu WKND peuvent modifier le nom du représentant ou de la représentante.
En outre, le numéro de téléphone est mis en forme différemment (en bleu), ce qui est un cas d’utilisation supplémentaire de la fonctionnalité des badges.
Pour simplifier les choses, cet exemple utilise le framework Adobe React Spectrum pour développer l’interface utilisateur du widget ou de la boîte de dialogue et les numéros de téléphone du service clientèle WKND codés en dur. Pour contrôler l’aspect non modifiable et de style du contenu, le caractère #
est utilisé dans les attributs prefix
et suffix
de la définition des badges.
Points d’extension
Cet exemple s’étend jusqu’au point d’extension rte
pour ajouter un badge au RTE dans l’éditeur de fragment de contenu.
Exemple d’extension
L’exemple suivant permet de créer un widget Service clientèle des réservations pour grands groupes. En appuyant sur la touche {
dans l’éditeur de texte enrichi, le menu contextuel des widgets RTE s’ouvre. En sélectionnant l’option Service clientèle des réservations pour grands groupes dans le menu contextuel, la boîte de dialogue modale personnalisée s’ouvre.
Une fois que le numéro de service clientèle souhaité est ajouté à partir de la boîte de dialogue modale, les badges rendent le numéro de téléphone non modifiable et le mettent en forme en bleu.
Enregistrement d’une extension
ExtensionRegistration.js
, mappé vers l’itinéraire index.html
, est le point d’entrée de l’extension AEM et définit les éléments suivants :
- La définition du badge est définie dans
getBadges()
à l’aide des attributs de configurationid
,prefix
,suffix
,backgroundColor
ettextColor
. - Dans cet exemple, le caractère
#
sert à définir les limites de ce badge, c’est-à-dire toute chaîne de l’éditeur de texte enrichi entourée de#
est traitée comme une instance de ce badge.
Consultez également les détails clés du widget RTE :
- La définition du widget dans la fonction
getWidgets()
avec les attributsid
,label
eturl
. - La valeur d’attribut
url
, un chemin d’URL relatif (/index.html#/largeBookingsCustomerService
) pour charger la boîte de dialogue modale.
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 Badges
getBadges: () => [
{
id: "phoneNumber",
prefix: "#",
suffix: "#",
backgroundColor: "",
textColor: "#071DF8",
},
],
// RTE Widgets
getWidgets: () => [
{
id: "largegroup-contact-list-widget",
label: "Large Group Bookings Customer Service",
url: "/index.html#/largeBookingsCustomerService",
},
],
},
},
});
};
init().catch(console.error);
return <Text>IFrame for integration with Host (AEM)...</Text>;
}
export default ExtensionRegistration;
Ajouter l’itinéraire largeBookingsCustomerService
dans App.js
Dans le composant React principal App.js
, ajoutez l’itinéraire largeBookingsCustomerService
pour effectuer le rendu de l’interface utilisateur pour le chemin d’URL relatif ci-dessus.
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="/largeBookingsCustomerService" element={<LargeBookingsCustomerService />} />
</Routes>
...
Créer le composant React LargeBookingsCustomerService
L’interface utilisateur du widget ou de la boîte de dialogue est créée à l’aide du framework Adobe React Spectrum.
Lors de l’ajout des informations du service clientèle, le code du composant React entoure la variable du numéro de téléphone avec les caractères #
de badges enregistrés pour le convertir en badges, comme #${phoneNumber}#
, le rendant ainsi non modifiable.
Voici les principaux points forts du code LargeBookingsCustomerService
:
- L’interface utilisateur est rendue à l’aide des composants React Spectrum, tels que ComboBox, ButtonGroup et Button.
- Le tableau
largeGroupCustomerServiceList
a un mappage codé en dur du nom du représentant ou de la représentante et du numéro de téléphone. Dans un scénario réel, ces données peuvent être récupérées à partir de l’action Adobe AppBuilder ou de systèmes externes, ou de la passerelle API locale ou basée sur le fournisseur cloud. - La fonction
guestConnection
est initialisée à l’aide duuseEffect
hook React et gérée en tant que statut du composant. Elle est utilisé pour communiquer avec l’hôte AEM. - La fonction
handleCustomerServiceChange
obtient le nom du représentant ou de la représentante et le numéro de téléphone, puis met à jour les variables de statut du composant. - La fonction
addCustomerServiceDetails
utilisant l’objetguestConnection
fournit des instructions d’exécution de l’éditeur de texte enrichi. Dans ce cas, l’instructioninsertContent
et l’extrait de code HTML. - Pour rendre le numéro de téléphone non modifiable à l’aide de badges, le caractère spécial
#
est ajouté avant et après la variablephoneNumber
, comme...<div><p>Phone Number: #${phoneNumber}#</strong></p></div>
.
src/aem-cf-editor-1/web-src/src/components/LargeBookingsCustomerService.js
import {
Button,
ButtonGroup,
Text,
Divider,
ComboBox,
Content, Flex, Form,
Item,
Provider, defaultTheme
} from '@adobe/react-spectrum';
import { attach } from '@adobe/uix-guest';
import React, { useEffect, useState } from 'react';
import { extensionId } from './Constants';
const LargeBookingsCustomerService = () => {
// The Large Group Bookings Customer Service
// 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 largeGroupCustomerServiceList = [
{ id: 1, repName: 'Max', phoneNumber: '1-800-235-1000' },
{ id: 2, repName: 'John', phoneNumber: '1-700-235-2000' },
{ id: 3, repName: 'Leah', phoneNumber: '1-600-235-3000' },
{ id: 4, repName: 'Leno', phoneNumber: '1-500-235-4000' }
];
// Set up state used by the React component
const [guestConnection, setGuestConnection] = useState();
// State hooks to manage the component state
const [repName, setRepName] = useState(null);
const [phoneNumber, setPhoneNumber] = 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 `customerService` Dropdown change
const handleCustomerServiceChange = (id) => {
if (id) {
//Get Customer Service RepName and Phone Number values using selected id
const rep = largeGroupCustomerServiceList.filter((r) => r.id === id)[0];
//update the `repName` state
setRepName(rep?.repName);
//update the `phoneNumber` state
setPhoneNumber(rep?.phoneNumber);
}
};
// Add the selected Customer Service details into the RTE
const addCustomerServiceDetails = () => {
if (repName && phoneNumber) {
// 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: `<div><p>Representative Name: <strong>${repName}</strong></p></div><div><p>Phone Number: #${phoneNumber}#</strong></p></div>` }]);
}
};
// Adobe React Spectrum (HTML code) that renders the Customer Service 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>Representative Name: <strong>{repName}</strong></Text>
<Text>Phone Number: <strong>{phoneNumber}</strong></Text>
<p />
<Divider size="M" />
<ComboBox
name="customerService"
label="Type or Select Phone Number"
defaultItems={largeGroupCustomerServiceList}
onSelectionChange={handleCustomerServiceChange}>
{item => <Item>{item.phoneNumber}</Item>}
</ComboBox>
<p />
<ButtonGroup align="right">
<Button variant="accent" onPress={addCustomerServiceDetails}>Add</Button>
<Button variant="secondary" onPress={() => {setPhoneNumber(null); setRepName(null);}}>Clear</Button>
</ButtonGroup>
</Form>
</Flex>
</Content>
</Provider>
);
};
export default LargeBookingsCustomerService;