将徽章添加到富文本编辑器(RTE)

了解如何在AEM内容片段编辑器中向富文本编辑器(RTE)添加徽章。

富文本编辑器徽章是使富文本编辑器(RTE)中的文本不可编辑的扩展。 这意味着声明为此类的徽章只能完全删除,不能部分编辑。 这些徽章还支持RTE中的特殊着色,明确向内容作者指示文本是徽章,因此不可编辑。 此外,它们提供有关徽章文本含义的视觉提示。

RTE徽章最常见的使用案例是与RTE小组件一起使用。 这允许RTE构件插入到RTE中的内容不可编辑。

通常,与构件关联的徽章用于添加具有外部系统依赖关系的动态内容,但​ 内容作者无法修改 ​插入的动态内容以保持完整性。 它们只能作为整个项目删除。

使用rte扩展点将​ 徽章 ​添加到内容片段编辑器中的​ RTE。 使用rte扩展点的getBadges()方法添加了一个或多个徽章。

此示例说明如何添加名为​ Large Group Bookings Customer Service ​的小部件,以在RTE内容中查找、选择并添加特定于WKND冒险的客户服务详细信息,如​ 代表姓名 ​和​ 电话号码。 使用徽章功能,电话号码 ​被设为​ 不可编辑,但WKND内容作者可以编辑代表姓名。

此外,电话号码 ​的样式不同(蓝色),这是徽章功能的额外用例。

为了简单起见,此示例使用AdobeReact Spectrum框架开发小部件或对话框UI以及硬编码的WKND客户服务电话号码。 为了控制内容的非编辑性和不同的样式方面,在徽章定义的prefixsuffix属性中使用#字符。

扩展点

此示例扩展到扩展点rte以在内容片段编辑器中向RTE添加徽章。

扩展示例

以下示例创建一个​ 大型群预订客户服务 ​构件。 通过在RTE中按{键,打开RTE构件上下文菜单。 通过从上下文菜单中选择​ Large Group Bookings Customer Service ​选项,将打开自定义模式。

从模式中添加所需的客户服务编号后,徽章会使​ 电话号码不可编辑 ​并将其样式设置为蓝色。

延期注册

映射到index.html路由的ExtensionRegistration.js是AEM扩展的入口点并定义:

  • getBadges()中使用配置属性idprefixsuffixbackgroundColortextColor定义了徽章的定义。
  • 在此示例中,#字符用于定义此徽章的边界,这意味着RTE中由#包围的任何字符串都被视为此徽章的实例。

此外,请参阅RTE小部件的关键详细信息:

  • getWidgets()中的构件定义具有idlabelurl属性。
  • url属性值,加载模态的相对URL路径(/index.html#/largeBookingsCustomerService)。

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;

App.js中添加largeBookingsCustomerService路由 add-widgets-route

在主React组件App.js中,添加largeBookingsCustomerService路由以呈现上述相对URL路径的UI。

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

创建LargeBookingsCustomerService React组件 create-widget-react-component

使用AdobeReact Spectrum框架创建构件或对话框UI。

添加客户服务详细信息时,React组件代码在电话号码变量周围使用#已注册的徽章字符将其转换为徽章,如#${phoneNumber}#,从而使它不可编辑。

以下是LargeBookingsCustomerService代码的关键亮点:

  • UI是使用React Spectrum组件呈现的,如ComboBoxButtonGroupButton
  • largeGroupCustomerServiceList数组具有代表性名称和电话号码的硬编码映射。 在现实场景中,此数据可以从AdobeAppBuilder操作或外部系统、自主开发或基于云提供商的API网关中检索。
  • 使用useEffect React挂接初始化guestConnection,并将其作为组件状态进行管理。 用于与AEM主机通信。
  • handleCustomerServiceChange函数获取代表性姓名和电话号码,并更新组件状态变量。
  • 使用guestConnection对象的addCustomerServiceDetails函数提供了要执行的RTE指令。 在本例中,insertContent说明和HTML代码段。
  • 为了使用徽章使​ 电话号码不可编辑,在phoneNumber变量之前和之后添加#特殊字符,如...<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