在AEM中编辑外部SPA

在决定外部SPA和AEM之间希望具有的集成级别时,您通常需要能够编辑并视图AEM。

概述

本文档介绍了将独立SPA上传到AEM实例、添加内容的可编辑部分以及启用创作的建议步骤。

前提条件

先决条件很简单。

将SPA上传到AEM项目

首先,您需要将外部SPA上传到AEM项目。

  1. /ui.frontend项目文件夹中的src替换为React应用程序的src文件夹。
  2. 在应用程序package.json/ui.frontend/package.json文件中包含任何其他依赖项。
  3. /public文件夹中包含所有自定义项。
  4. 包括在/public/index.html文件中添加的任何内联脚本或样式。

配置远程SPA

由于外部SPA是AEM项目的一部分,因此需要在AEM中配置它。

包括AdobeSPA SDK包

要利用AEM SPA功能,需要依赖以下三个包。

@adobe/aem-spa-page-model-manager 提供用于初始化模型管理器并从AEM实例检索模型的API。然后,此模型可用于使用@adobe/aem-react-editable-components@adobe/aem-spa-component-mapping的API渲染AEM组件。

安装

运行以下npm命令以安装所需的包。

npm install --save @adobe/aem-spa-component-mapping @adobe/aem-spa-page-model-manager @adobe/aem-react-editable-components

ModelManager初始化

在应用程序呈现之前,ModelManager需要进行初始化以处理AEM ModelStore的创建。

这需要在应用程序的src/index.js文件中或在呈现应用程序根目录的任何地方完成。

对于此,我们可以使用ModelManager提供的initializationAsync API。

以下屏幕截图显示了如何在简单的React应用程序中启用初始化ModelManager。 唯一的约束是initializationAsync需要在ReactDOM.render()之前调用。

初始化ModelManager

在此示例中,初始化ModelManager并创建空的ModelStore

initializationAsync 可以选择接 options 受对象作为参数:

  • path -初始化时,将读取定义路径上的模型并将其存储在 ModelStore。如果需要,可以在初始化时使用它获取rootModel
  • modelClient -允许提供负责获取模型的自定义客户端。
  • model -使用 model SSR时通常填充为参数 的对象。

AEM可创作的Leaf组件

  1. 创建/标识将为其创建可授权React组件的AEM组件。 在此示例中,我们使用WKND项目的文本组件。

    WKND文本组件

  2. 在SPA中创建一个简单的React文本组件。 在此示例中,已使用以下内容创建了新文件Text.js

    Text.js

  3. 创建配置对象以指定启用AEM编辑所需的属性。

    创建配置对象

    • resourceType 必须将React组件映射到AEM组件,并在AEM编辑器中打开时启用编辑。
  4. 使用包装函数withMappable

    与Mappable一起使用

    此包装器函数将React组件映射到配置中指定的AEM resourceType,并在AEM编辑器中打开时启用编辑功能。 对于独立组件,它还将获取特定节点的模型内容。

    注意

    在此示例中,组件有不同版本:AEM封装和未封装的React组件。 显式使用组件时,需要使用打包版本。 当组件是页面的一部分时,您可以继续使用默认组件,就像当前在SPA编辑器中一样。

  5. 渲染组件中的内容。

    文本组件的JCR属性在AEM中显示如下。

    文本组件属性

    这些值将作为属性传递给新创建的AEMText React组件,并可用于呈现内容。

    import React from 'react';
    import { withMappable } from '@adobe/aem-react-editable-components';
    
    export const TextEditConfig = {
        // Empty component placeholder label
        emptyLabel:'Text', 
        isEmpty:function(props) {
           return !props || !props.text || props.text.trim().length < 1;
        },
        // resourcetype of the AEM counterpart component
        resourceType:'wknd-spa-react/components/text'
    };
    
    const Text = ({ text }) => (<div>{text}</div>);
    
    export default Text;
    
    export const AEMText = withMappable(Text, TextEditConfig);
    

    这是AEM配置完成后组件的显示方式。

    const Text = ({ cqPath, richText, text }) => {
       const richTextContent = () => (
          <div className="aem_text" id={cqPath.substr(cqPath.lastIndexOf('/') + 1)} data-rte-editelement dangerouslySetInnerHTML={{__html: text}}/>
       );
       return richText ? richTextContent() : (<div className="aem_text">{text}</div>);
    };
    
    注意

    在此示例中,我们对渲染的组件进行了进一步自定义以匹配现有文本组件。 但这与在AEM中进行创作无关。

将可创作组件添加到页面

创建可创作的React组件后,我们可以在整个应用程序中使用它们。

让我们举一个示例页,其中需要从WKND SPA项目添加文本。 在此示例中,我们要显示文本“Hello World!” on /content/wknd-spa-react/us/en/home.html.

  1. 确定要显示的节点的路径。

    • pagePath:包含节点的页面,在我们的示例中 /content/wknd-spa-react/us/en/home
    • itemPath:页面中节点的路径,在我们的示例中 root/responsivegrid/text
      • 这由页面上包含项目的名称组成。

    节点的路径

  2. 在页面中的所需位置添加组件。

    将组件添加到页面

    AEMText组件可以添加到页面中的所需位置,其中pagePathitemPath值设置为属性。 pagePath 是强制属性。

验证编辑AEM上的文本内容

我们现在可以在运行的AEM实例上测试该组件。

  1. aem-guides-wknd-spa目录运行以下Maven命令以构建项目并将其部署到AEM。
mvn clean install -PautoInstallSinglePackage
  1. 在AEM实例上,导航到http://<host>:<port>/editor.html/content/wknd-spa-react/us/en/home.html

在AEM中编辑SPA

AEMText组件现在可在AEM上授权。

AEM可创作页面

  1. 确定要在SPA中添加以进行创作的页面。 此示例使用/content/wknd-spa-react/us/en/home.html

  2. 创建新文件(例如,Page.js)。 在此,我们可以重用@adobe/cq-react-editable-components中提供的页面组件。

  3. AEM可创作叶组件部分中重复步骤4。 对组件使 withMappable 用包装器函数。

  4. 如之前所述,将MapTo应用于页面中所有子组件的AEM资源类型。

    import { Page, MapTo, withMappable } from '@adobe/aem-react-editable-components';
    import Text, { TextEditConfig } from './Text';
    
    export default withMappable(Page);
    
    MapTo('wknd-spa-react/components/text')(Text, TextEditConfig);
    
    注意

    在此示例中,我们使用未封装的React文本组件,而不是先前创建的封装的AEMText。 这是因为当组件是页面/容器的一部分,而不是独立的时候,容器将负责定期映射组件并启用创作功能,而且每个子级不需要额外的包装器。

  5. 要在SPA中添加可创作页面,请按照将可创作组件添加到页面中的相同步骤操作。 但是,我们可以跳过 itemPath 该属性。

验证AEM上的页面内容

要验证页面是否可以编辑,请按照AEM上验证文本内容编辑部分中的相同步骤操作。

在AEM中编辑页面

现在可在AEM上使用布局容器和子文本组件编辑页面。

虚拟叶组件

在前面的示例中,我们将组件添加到SPA中并包含现有AEM内容。 但是,有些情况下,内容尚未在AEM中创建,但需要由内容作者稍后添加。 为了适应这种情况,前端开发人员可以在SPA的适当位置添加组件。 这些组件在AEM的编辑器中打开时将显示占位符。 内容作者在这些占位符中添加内容后,将以JCR结构创建节点并保留内容。 创建的组件将允许与独立的叶组件相同的操作集。

在此示例中,我们将重复使用先前创建的AEMText组件。 我们希望在WKND主页的现有文本组件下添加新文本。 添加的组件与添加常规叶组件相同。 但是,itemPath可以更新到需要添加新组件的路径。

由于新组件需要添加到root/responsivegrid/text的现有文本下,因此新路径应为root/responsivegrid/{itemName}

<AEMText
 pagePath='/content/wknd-spa-react/us/en/home'
 itemPath='root/responsivegrid/text_20' />

添加虚拟组件后,TestPage组件如下所示。

测试虚拟组件

注意

确保AEMText组件在配置中设置了resourceType以启用此功能。

现在,您可以按照AEM上验证文本内容编辑部分中的步骤将更改部署到AEM。 将显示当前非现有节点的占位符 text_20

aem中的text_20节点

当内容作者更新此组件时,将在/content/wknd-spa-react/us/en/homeroot/responsivegrid/text_20上创建新的text_20节点。

text20节点

要求和限制

添加虚拟叶组件有许多要求,并存在一些限制。

  • 创建虚拟组件时,pagePath属性是必填项。
  • pagePath路径中提供的页面节点必须存在于AEM项目中。
  • 要创建的节点的名称必须在itemPath中提供。
  • 可在任何级别创建组件。
    • 如果我们在上一个示例中提供itemPath='text_20',则新节点将直接在页面下创建,即/content/wknd-spa-react/us/en/home/jcr:content/text_20
  • 当通过itemPath提供时,创建新节点的节点的路径必须有效。
    • 在此示例中,root/responsivegrid必须存在,这样新节点text_20就可以在此处创建。
  • 仅支持创建叶组件。 将来版本将支持虚拟容器和页面。

其他自定义

如果您按照以前的示例操作,您的外部SPA现在可在AEM中编辑。 但是,外部SPA还有其他方面可供您进一步自定义。

根节点ID

默认情况下,我们假定React应用程序呈现在元素ID spa-rootdiv中。 如果需要,可以自定义此项。

例如,假定我们有一个SPA,其中应用程序呈现在元素ID rootdiv中。 这需要反映在三个文件中。

  1. 在React应用程序的index.js中(或调用ReactDOM.render()的位置)

    index.js文件中的ReactDOM.render()

  2. 在React应用程序的index.html

    应用程序的index.html

  3. 在AEM应用程序的页面组件主体中,通过两个步骤:

    1. 为页面组件新建body.html

    创建新body.html文件

    1. 在新的body.html文件中添加新的根元素。

    将根元素添加到body.html

使用路由编辑React SPA

如果外部React SPA应用程序有多个页面,它可以使用路由确定要呈现的页面/组件。 基本用例是将当前活动的URL与为路由提供的路径匹配。要在启用路由的应用程序上启用编辑,需要转换要与之匹配的路径以适应AEM特定信息。

在以下示例中,我们有一个简单的React应用程序,它包含两页。 要呈现的页面是通过将提供给路由器的路径与活动URL进行匹配来确定的。 例如,如果我们位于mydomain.com/test上,则将呈现TestPage

路由外部SPA

要在AEM中为此示例启用编辑,需要执行以下步骤。

  1. 确定作为AEM根的级别。

    • 对于我们的样本,我们考虑将wknd-spa-react/us/en作为SPA的根。 这意味着该路径之前的所有内容都仅为AEM页面/内容。
  2. 在所需级别创建新页面。

    • 在此示例中,要编辑的页面为mydomain.com/testtest 位于应用程序的根路径中。在AEM中创建页面时也需要保留该属性。 因此,我们可以在上一步中定义的根级别创建新页面。
    • 创建的新页面必须与要编辑的页面具有相同的名称。 在此示例中,对于mydomain.com/test,创建的新页面必须为/path/to/aem/root/test
  3. 在SPA路由中添加帮手。

    • 新创建的页面尚不会在AEM中呈现预期内容。 这是因为路由器希望路径为/test ,而AEM活动路径为/wknd-spa-react/us/en/test。 要适应AEM特定URL的部分,我们需要在SPA端添加一些帮手。

    路由帮助器

    • @adobe/cq-spa-page-model-manager提供的toAEMPath帮助程序可用于此。 当应用程序在AEM实例上打开时,它会将为路由提供的路径转换为包含AEM特定部分。 它接受三个参数:
      • 路由所需的路径
      • 编辑SPA的AEM实例的来源URL
      • AEM上的项目根(在第一步中确定)
    • 这些值可设置为环境变量,以提高灵活性。
  4. 验证在AEM中编辑页面。

    • 将项目部署到AEM并导航到新创建的test页面。 页面内容现在呈现,AEM组件可编辑。

其他资源

以下参考资料有助于在AEM的上下文中了解SPA。

On this page

Adobe Summit Banner

A virtual event April 27-28.

Expand your skills and get inspired.

Register for free
Adobe Summit Banner

A virtual event April 27-28.

Expand your skills and get inspired.

Register for free
Adobe Maker Awards Banner

Time to shine!

Apply now for the 2021 Adobe Experience Maker Awards.

Apply now
Adobe Maker Awards Banner

Time to shine!

Apply now for the 2021 Adobe Experience Maker Awards.

Apply now