Hinzufügen von Badges zum Rich-Text-Editor (RTE)

Erfahren Sie, wie Sie im AEM-Inhaltsfragmenteditor Badges zum Rich-Text-Editor (RTE) hinzufügen.

Rich-Text-Editor-Badges sind Erweiterungen, die Text im Rich-Text-Editor (RTE) unbearbeitbar machen. Das bedeutet, dass ein als solches deklariertes Badge nur vollständig entfernt, aber nicht teilweise bearbeitet werden kann. Diese Badges unterstützen auch eine spezielle Färbung im RTE, die Inhaltsautorinnen und Inhaltsautoren deutlich zeigt, dass der Text ein Badge ist und daher nicht bearbeitbar ist. Darüber hinaus bieten sie visuelle Hinweise zur Bedeutung des Badge-Textes.

Der häufigste Anwendungsfall für RTE-Badges besteht darin, diese zusammen mit RTE-Widgets zu verwenden. Dadurch können Inhalte, die vom RTE-Widget in den RTE eingefügt werden, nicht bearbeitet werden.

Typischerweise werden die Badges in Verbindung mit den Widgets verwendet, um den dynamischen Inhalt hinzuzufügen, der eine externe Systemabhängigkeit hat, aber Inhaltsautorinnen und Inhaltsautoren können den eingefügten dynamischen Inhalt nicht ändern, damit die Integrität gewahrt wird. Sie können nur als ganzes Element entfernt werden.

Die Badges werden dem RTE im Inhaltsfragmenteditor über den Erweiterungspunkt rte hinzugefügt. Mit der Methode getBadges() des Erweiterungspunkts rte werden ein oder mehrere Badges hinzugefügt.

Dieses Beispiel zeigt, wie man ein Widget mit dem Namen Großgruppenbuchungen-Kundenservice hinzufügt, um die abenteuerspezifischen WKND-Kundenservice-Details wie Vertretername und Telefonnummer innerhalb eines RTE-Inhalts zu finden, auszuwählen und hinzuzufügen. Mithilfe der Badges-Funktion wird die Telefonnummer unbearbeitbar, aber WKND-Inhaltsautorinnen und -Inhaltsautoren können den Vertreternamen bearbeiten.

Außerdem ist die Telefonnummer anders gestaltet (blau), was ein zusätzlicher Anwendungsfall für die Badges-Funktion ist.

Um die Dinge einfach zu halten, verwendet dieses Beispiel das Adobe React Spectrum-Framework, um die Widget- oder Dialog-UI und die fest codierten Telefonnummern des WKND-Kundendienstes zu entwickeln. Um den Aspekt der Nicht-Bearbeitung und des unterschiedlichen Stils des Inhalts zu kontrollieren, wird das Zeichen # in den Attributen prefix und suffix der Badges-Definition verwendet.

Erweiterungspunkte

Dieses Beispiel erstreckt sich auf den Erweiterungspunkt rte, um dem RTE im Inhaltsfragmenteditor ein Badge hinzuzufügen.

Erweiterte AEM-Benutzeroberfläche
Erweiterungspunkte
Inhaltsfragmenteditor
Rich-Text-Editor-Badges und Rich-Text-Editor-Widgets

Beispielerweiterung

Das folgende Beispiel erstellt ein Widget namens Großgruppenbuchungen-Kundendienst. Durch Drücken der Taste { im RTE wird das Kontextmenü der RTE-Widgets geöffnet. Durch Auswahl der Option Großgruppenbuchungen-Kundenservice aus dem Kontextmenü wird das benutzerdefinierte Modal geöffnet.

Sobald die gewünschte Kundendienstnummer aus dem Modal hinzugefügt wird, machen die Badges die Telefonnummer unbearbeitbar und gestalten sie in blauer Farbe.

Registrierung der Erweiterung

ExtensionRegistration.js, das der Route index.html zugeordnet ist, ist der Einstiegspunkt für die AEM-Erweiterung und definiert:

  • Die Definition des Badges wird in getBadges() unter Verwendung der Konfigurationsattribute id, prefix, suffix, backgroundColor und textColor festgelegt.
  • In diesem Beispiel wird das Zeichen # verwendet, um die Grenzen dieses Badges zu definieren. Das bedeutet, dass jede Zeichenkette im RTE, die von # umgeben ist, als eine Instanz dieses Badges behandelt wird.

Weitere Informationen sehen Sie in den Schlüsseldetails des RTE-Widgets:

  • Die Widget-Definition in der Funktion getWidgets() mit den Attributen id, label und url.
  • Der url-Attributwert, ein relativer URL-Pfad (/index.html#/largeBookingsCustomerService) zum Laden des Modals.

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;

Hinzufügen einer Route largeBookingsCustomerService in App.js

Fügen Sie in der React-Hauptkomponente App.js die Route largeBookingsCustomerService hinzu, um die Benutzeroberfläche für den oben genannten relativen URL-Pfad zu rendern.

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>
...

Erstellen der React-Komponente LargeBookingsCustomerService

Die Widget- oder Dialog-UI wird mit dem Adobe React Spectrum-Framework erstellt.

Der Code der React-Komponente beim Hinzufügen der Kundendienstdetails umgibt die Telefonnummer-Variable mit dem Zeichen für #-registrierte Badges, um sie in Badges zu konvertieren, wie #${phoneNumber}#, und macht sie somit unbearbeitbar.

Hier die wichtigsten Punkte vom LargeBookingsCustomerService-Code:

  • Die UI wird mit React Spectrum-Komponenten gerendert, z. B.ComboBox, ButtonGroup und Button
  • Das largeGroupCustomerServiceList-Array verfügt über eine fest kodierte Zuordnung von Name und Telefonnummer der oder des Mitarbeitenden. In einem realen Szenario können diese Daten von der Adobe AppBuilder-Aktion oder von externen Systemen oder von einem selbst entwickelten oder auf einem Cloud-Anbieter basierenden API-Gateway abgerufen werden.
  • Die guestConnection wird mithilfe des useEffect React-Hooks initialisiert und als Komponentenstatus verwaltet. Das Objekt wird zur Kommunikation mit dem AEM-Host verwendet.
  • Die Funktion handleCustomerServiceChange ruft den Namen und die Telefonnummer der oder des Mitarbeitenden ab und aktualisiert die Komponentenstatusvariablen.
  • Die Funktion addCustomerServiceDetails stellt unter Ausführung des Objekts guestConnection die auszuführende RTE-Anweisung bereit. In diesem Fall die Anweisung insertContent und ein HTML-Code-Snippet.
  • Um die Telefonnummer mit Hilfe von Badges uneditierbar zu machen, wird das Sonderzeichen # vor und nach der phoneNumber-Variablen hinzugefügt, wie in ...<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;
recommendation-more-help
4859a77c-7971-4ac9-8f5c-4260823c6f69