在决定外部SPA与Adobe Experience Manager (AEM)之间的集成级别时,您通常需要能够在AEM中编辑和查看SPA。
本文档介绍了将独立SPA上传到AEM实例、添加可编辑的内容部分和启用创作的建议步骤。
先决条件很简单。
首先,您需要将外部SPA上传到AEM项目。
src
在 /ui.frontend
使用React应用程序的 src
文件夹。package.json
在 /ui.frontend/package.json
文件。
/public
文件夹。/public/index.html
文件。现在,外部SPA已成为AEM项目的一部分,因此必须在AEM中对其进行配置。
要利用AEM SPA功能,需要依赖以下三个软件包。
@adobe/aem-react-editable-components
@adobe/aem-spa-component-mapping
@adobe/aem-spa-page-model-manager
此 @adobe/aem-spa-page-model-manager
提供用于初始化模型管理器和从AEM实例检索模型的API。 然后,此模型可用于使用来自的API渲染AEM组件 @adobe/aem-react-editable-components
和 @adobe/aem-spa-component-mapping
.
运行以下npm命令以安装所需的软件包。
npm install --save @adobe/aem-spa-component-mapping @adobe/aem-spa-page-model-manager @adobe/aem-react-editable-components
在应用程序渲染之前, ModelManager
必须初始化才能处理AEM的创建 ModelStore
.
这需要在以下时间内完成: src/index.js
应用程序的文件,或在呈现应用程序根目录的位置。
为此,请使用 initializationAsync
API由提供 ModelManager
.
以下屏幕截图显示了如何启用 ModelManager
在简单的React应用程序中。 唯一的限制是 initializationAsync
必须在之前调用 ReactDOM.render()
.
在此示例中, ModelManager
已初始化并且为空 ModelStore
创建。
此 initializationAsync
可以选择接受 options
对象作为参数:
path
— 初始化时,将获取定义路径处的模型并将其存储在 ModelStore
. 这可用于获取 rootModel
初始化时(如果需要)。modelClient
— 允许提供负责提取模型的自定义客户端。model
- A model
作为参数传递的对象通常填充于 使用SSR。创建/标识将为其创建可授权的React组件的AEM组件。 在此示例中,WKND项目使用文本组件。
在SPA中创建简单的React文本组件。 在本例中,是一个新文件 Text.js
已创建,内容如下。
创建配置对象以指定启用AEM编辑所需的属性。
resourceType
是将React组件映射到AEM组件并在AEM编辑器中打开时启用编辑功能的必需组件。使用包装函数 withMappable
.
此包装函数将React组件映射到AEM resourceType
在配置中指定,并在AEM编辑器中打开时启用编辑功能。 对于独立组件,它还会获取特定节点的模型内容。
在此示例中,该组件有单独的版本:AEM封装和未封装的React组件。 显式使用组件时,需要使用包装的版本。 当组件是页面的一部分时,您可以继续使用默认组件,就像当前在SPA编辑器中完成的那样。
呈现组件中的内容。
文本组件的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!” 开启 /content/wknd-spa-react/us/en/home.html
.
确定要显示的节点的路径。
pagePath
:示例中包含节点的页面 /content/wknd-spa-react/us/en/home
itemPath
:页面中节点的路径,如示例 root/responsivegrid/text
在页面中的所需位置添加组件。
此 AEMText
组件可以通过添加到页面的所需位置 pagePath
和 itemPath
值设置为属性。 pagePath
是必需属性。
现在,请在正在运行的AEM实例上测试该组件。
aem-guides-wknd-spa
目录,以生成项目并将其部署到AEM。mvn clean install -PautoInstallSinglePackage
http://<host>:<port>/editor.html/content/wknd-spa-react/us/en/home.html
.此 AEMText
组件现在可在AEM上创作。
标识要在SPA中添加以进行创作的页面。 此示例使用 /content/wknd-spa-react/us/en/home.html
.
创建文件(例如, Page.js
)。 在这里,可以重用中提供的页面组件 @adobe/cq-react-editable-components
.
在部分中重复步骤4 AEM可授权的叶组件. 使用包装函数 withMappable
在组件上。
与之前一样,应用 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
之前创建。 这是因为当组件是页面/容器的一部分并且不是独立组件时,容器将负责递归映射组件并启用创作功能,并且每个子组件不需要额外的包装器。
要在SPA中添加可创作页面,请执行部分中的相同步骤 将可创作组件添加到页面. 我们可以跳过 itemPath
属性。
要验证是否可以编辑页面,请执行部分中的相同步骤 验证在AEM上编辑文本内容.
现在,该页面可以在带有布局容器和子文本组件的AEM上编辑。
在前面的示例中,我们使用现有AEM内容将组件添加到SPA。 但是,在某些情况下,内容尚未在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
节点。
当内容作者更新此组件时,将使用 text_20
节点创建于 root/responsivegrid/text_20
在 /content/wknd-spa-react/us/en/home
.
添加虚拟叶组件有几项要求以及一些限制。
pagePath
属性是创建虚拟组件的必需属性。pagePath
必须存在于AEM项目中。itemPath
.itemPath='text_20'
在上一个示例中,将直接在页面(即 /content/wknd-spa-react/us/en/home/jcr:content/text_20
itemPath
.
root/responsivegrid
必须存在,以便新节点 text_20
可以在那里创建。支持添加容器的功能,即使尚未在AEM中创建相应的容器。 其概念和方法类似于 虚拟叶组件。
前端开发人员可以将容器组件添加到SPA内的相应位置,这些组件在AEM的编辑器中打开时将显示占位符。 然后,作者可以将组件及其内容添加到容器中,容器将在JCR结构中创建所需的节点。
例如,如果容器已存在于 /root/responsivegrid
并且开发人员想要添加一个新的子容器:
newContainer
在AEM中尚不存在。
在AEM中编辑包含此组件的页面时,会显示一个空的容器占位符,作者可以在其中添加内容。
作者向容器中添加子组件后,将创建一个新的容器节点,该节点的JCR结构中具有对应的名称。
现在,可以根据作者的需要向容器中添加更多组件和内容,所做的更改将会保留。
添加虚拟容器有几项要求以及一些限制。
root/responsivegrid
AEM容器中已存在,则可以通过提供路径来创建新容器 root/responsivegrid/newContainer
.root/responsivegrid/newContainer/secondNewContainer
是不可能的。如果您按照上面的示例进行操作,则现在可以在AEM中编辑外部SPA。 但是,您可以进一步自定义外部SPA的其他方面。
默认情况下,我们假定React应用程序呈现在内部, div
元素ID的 spa-root
. 如果需要,可以自定义设置。
例如,假设我们有一个SPA,其中应用程序呈现在 div
元素ID的 root
. 这需要在三个文件中反映出来。
在 index.js
React应用程序的(或 ReactDOM.render()
称为)
在 index.html
React应用程序的
在AEM应用程序的页面组件正文中,执行以下两个步骤:
body.html
页面组件的。body.html
文件。如果外部React SPA应用程序有多个页面, 它可以使用路由来确定要渲染的页面/组件. 基本用例是将当前活动的URL与为路由提供的路径进行匹配。 要在此类启用路由的应用程序中启用编辑,需要转换要匹配的路径以适应AEM特定的信息。
在以下示例中,我们有一个包含两个页面的简单React应用程序。 要渲染的页面是通过将提供给路由器的路径与活动URL进行匹配来确定的。 例如,如果为 mydomain.com/test
, TestPage
将呈现。
要在AEM中为此示例SPA启用编辑,需要执行以下步骤。
确定将用作AEM根目录的级别。
wknd-spa-react/us/en
作为SPA的根目录。 这意味着,该路径之前的所有内容仅包含AEM页面/内容。在所需级别创建新页面。
mydomain.com/test
. test
在应用程序的根路径中。 在AEM中创建页面时,也需要保留此设置。 因此,我们可以在上一步中定义的根级别创建新页面。mydomain.com/test
,则创建的新页面必须 /path/to/aem/root/test
.在SPA路由中添加帮助程序。
/test
而AEM活动路径为 /wknd-spa-react/us/en/test
. 为了适应URL的特定于AEM的部分,我们需要在SPA端添加一些帮助程序。此 toAEMPath
帮助程序提供者 @adobe/cq-spa-page-model-manager
可用于此目的。 当应用程序在AEM实例上打开时,它会转换为路由提供的路径,以包含AEM特定的部分。 它接受三个参数:
可以将这些值设置为环境变量,以获得更大的灵活性。
验证是否在AEM中编辑页面。
test
页面。 页面内容现已呈现,并且AEM组件可编辑。RemotePage组件要求实施提供与资产清单类似的资产清单 在此处找到. 但是,RemotePage组件仅经过测试,可以与React框架(和通过remote-page-next组件的Next.js)配合使用,因此不支持从其他框架(如Angular)远程加载应用程序。
以下参考资料可能有助于了解AEM上下文中的SPA。