将SPA组件映射到AEM组件 map-components
了解如何使用AEM SPA编辑器JS SDK将React组件映射到Adobe Experience Manager (AEM)组件。 组件映射使用户能够对AEM SPA编辑器中的SPA组件进行动态更新,这与传统AEM创作类似。
本章更深入地介绍了AEM JSON模型API,以及如何将由AEM组件公开的JSON内容作为prop自动插入到React组件中。
目标
- 了解如何将AEM组件映射到SPA组件。
- Inspect React组件如何使用从AEM传递的动态属性。
- 了解如何使用现成的React AEM核心组件。
您将构建的内容
本章检查提供的Text
SPA组件如何映射到AEM Text
组件。 React核心组件(如Image
SPA组件)在SPA中使用并在AEM中创作。 布局容器 和 模板编辑器 策略的现成功能也用于创建外观变化稍大的视图。
先决条件
查看设置本地开发环境所需的工具和说明。 本章是集成SPA章节的延续,但您需要遵循的是一个启用SPA的AEM项目。
映射方法
基本概念是将SPA组件映射到AEM组件。 AEM组件运行服务器端,将内容导出为JSON模型API的一部分。 JSON内容由SPA使用,在浏览器中运行客户端。 在SPA组件和AEM组件之间创建1:1映射。
将AEM组件映射到React组件的高级概述
Inspect文本组件
AEM项目原型提供了一个映射到AEM 文本组件的Text
组件。 这是 content 组件的示例,该组件渲染来自AEM的 content。
我们来看看组件的工作方式。
Inspect的JSON模型
-
在跳转到SPA代码之前,请务必了解AEM提供的JSON模型。 导航到核心组件库并查看文本组件的页面。 核心组件库提供了所有AEM核心组件的示例。
-
为以下示例之一选择 JSON 选项卡:
您应该看到三个属性:
text
、richText
和:type
。:type
是一个保留属性,它列出了AEM组件的sling:resourceType
(或路径)。:type
的值用于将AEM组件映射到SPA组件。text
和richText
是对SPA组件公开的其他属性。 -
在http://localhost:4502/content/wknd-spa-react/us/en.model.json处查看JSON输出。 您应该能够找到类似于以下内容的条目:
code language-json "text": { "id": "text-a647cec03a", "text": "<p>Hello World! Updated content!</p>\r\n", "richText": true, ":type": "wknd-spa-react/components/text", "dataLayer": {} }
Inspect文本SPA组件
-
在您选择的IDE中,打开SPA的AEM项目。 展开
ui.frontend
模块并在ui.frontend/src/components/Text/Text.js
下打开文件Text.js
。 -
我们将检查的第一个区域是位于~第40行的
class Text
:code language-js class Text extends Component { get richTextContent() { return (<div id={extractModelId(this.props.cqPath)} data-rte-editelement dangerouslySetInnerHTML={{__html: DOMPurify.sanitize(this.props.text)}} /> ); } get textContent() { return <div>{this.props.text}</div>; } render() { return this.props.richText ? this.richTextContent : this.textContent; } }
Text
是标准React组件。 组件使用this.props.richText
来确定要呈现的内容是富文本还是纯文本。 实际使用的“内容”来自this.props.text
。为避免潜在的XSS攻击,富文本在使用dangullySetInnerHTML呈现内容之前通过
DOMPurify
进行转义。 在练习的前面从JSON模型中撤回richText
和text
属性。 -
接下来,打开
ui.frontend/src/components/import-components.js
查看~第86行上的TextEditConfig
:code language-js const TextEditConfig = { emptyLabel: 'Text', isEmpty: function(props) { return !props || !props.text || props.text.trim().length < 1; } };
上述代码负责确定何时在AEM创作环境中呈现占位符。 如果
isEmpty
方法返回 true,则会呈现占位符。 -
最后,查看第94行以下位置的
MapTo
调用:code language-js export default MapTo('wknd-spa-react/components/text')(LazyTextComponent, TextEditConfig);
MapTo
由AEM SPA编辑器JS SDK (@adobe/aem-react-editable-components
)提供。 路径wknd-spa-react/components/text
表示AEM组件的sling:resourceType
。 此路径与之前观察到的JSON模型公开的:type
匹配。MapTo
负责解析JSON模型响应并将正确的值作为props
传递给SPA组件。您可以在
ui.apps/src/main/content/jcr_root/apps/wknd-spa-react/components/text
找到AEMText
组件定义。
使用React核心组件
AEM WCM组件 — React Core实施和AEM WCM组件 — Spa编辑器 — React Core实施。 这是一组可重复使用的UI组件,这些组件映射到开箱即用的AEM组件。 大多数项目可以重复使用这些组件作为自己的实施的起点。
-
在项目代码中,打开位于
ui.frontend/src/components
的文件import-components.js
。
此文件会导入映射到SPA组件的所有AEM组件。 考虑到SPA编辑器实施的动态性质,我们必须显式引用任何与SPA可创作组件绑定的AEM组件。 这允许AEM作者选择在应用程序中随处使用组件。 -
以下import语句包含在项目中编写的SPA组件:
code language-js import './Page/Page'; import './Text/Text'; import './Container/Container'; import './ExperienceFragment/ExperienceFragment';
-
存在来自
@adobe/aem-core-components-react-spa
和@adobe/aem-core-components-react-base
的其他imports
。 这些调用将导入React核心组件,并在当前项目中使其可用。 然后使用MapTo
将这些组件映射到项目特定的AEM组件,就像前面的Text
组件示例一样。
更新AEM策略
策略是AEM模板的一项功能,它让开发人员和高级用户能够精细地控制可以使用哪些组件。 React核心组件包含在SPA代码中,但需要通过策略启用,然后才能在应用程序中使用。
-
从AEM开始屏幕导航到 工具 > 模板 > WKND SPA React。
-
选择并打开 SPA Page 模板以进行编辑。
-
选择 布局容器 并单击它的 策略 图标以编辑策略:
-
在 允许的组件 > WKND SPA React - Content >检查 图像、Teaser 和 标题 下。
在 默认组件 > 添加映射 下,并选择 图像 — WKND SPA React - Content 组件:
输入
image/*
的 MIME类型。单击 完成 以保存策略更新。
-
在 布局容器 中,单击 文本 组件的 策略 图标。
创建名为 WKND SPA Text 的新策略。 在 插件 > 格式 >下,选中所有框以启用其他格式选项:
在 插件 > 段落样式 >下,选中 启用段落样式 的框:
单击 完成 以保存策略更新。
创作内容
-
导航到 主页 http://localhost:4502/editor.html/content/wknd-spa-react/us/en/home.html。
-
您现在应该能够在页面上使用其他组件 Image、Teaser 和 Title。
-
您还应该能够编辑
Text
组件并在 全屏 模式下添加其他段落样式。 -
您还应该能够从 资产查找器 中拖放图像:
-
使用 Title 和 Teaser 组件进行试验。
-
通过AEM Assets添加您自己的映像,或者为标准WKND引用站点安装完成的代码库。 WKND引用站点包含可在WKND SPA上重复使用的许多图像。 可以使用AEM包管理器安装包。
Inspect布局容器
AEM SPA编辑器SDK自动提供对 布局容器 的支持。 名称指示的 布局容器 是 容器 组件。 容器组件是接受JSON结构的组件,该结构表示 其他 组件并动态实例化它们。
让我们进一步检查布局容器。
-
在浏览器中导航到http://localhost:4502/content/wknd-spa-react/us/en.model.json
布局容器 组件具有
wcm/foundation/components/responsivegrid
的sling:resourceType
,并且被SPA编辑器使用:type
属性识别,就像Text
和Image
组件一样。SPA编辑器中提供了使用布局模式重新调整组件大小的相同功能。
-
返回到http://localhost:4502/editor.html/content/wknd-spa-react/us/en/home.html。 添加其他 图像 组件,然后尝试使用 布局 选项重新调整其大小:
-
重新打开JSON模型http://localhost:4502/content/wknd-spa-react/us/en.model.json并观察作为JSON一部分的
columnClassNames
:类名
aem-GridColumn--default--4
指示组件应基于12列网格为4列宽。 有关响应式网格的更多详细信息见此处。 -
返回到IDE,在
ui.apps
模块中ui.apps/src/main/content/jcr_root/apps/wknd-spa-react/clientlibs/clientlib-grid
处定义了客户端库。 打开文件less/grid.less
。此文件确定 布局容器 使用的断点(
default
、tablet
和phone
)。 此文件将根据项目规范进行自定义。 当前断点设置为1200px
和768px
。 -
您应该能够使用
Text
组件的响应式功能和更新的富文本策略来创作类似于以下内容的视图:
恭喜! congratulations
恭喜,您已了解如何将SPA组件映射到AEM组件,并且使用了React核心组件。 您还有机会探索 布局容器 的响应式功能。
后续步骤 next-steps
导航和路由 — 了解如何使用SPA编辑器SDK映射到AEM页面,从而支持SPA中的多个视图。 动态导航是使用React Router和React Core Components实现的。
(额外练习)将配置保留到源代码管理 bonus-configs
在许多情况下,尤其是在AEM项目开始时,将配置(如模板和相关内容策略)保留到源代码控制中非常有用。 这可确保所有开发人员都针对同一组内容和配置工作,并可确保环境之间具有额外的一致性。 一旦项目达到一定的成熟度,管理模板的操作就可以交给一组特殊的超级用户。
接下来的几个步骤将使用Visual Studio Code IDE和VSCode AEM Sync执行,但可以使用任何工具和您已配置为从AEM的本地实例 提取 或 导入 内容的任何IDE执行。
-
在Visual Studio Code IDE中,确保已通过Marketplace扩展安装 VSCode AEM Sync:
-
在项目资源管理器中展开 ui.content 模块并导航到
/conf/wknd-spa-react/settings/wcm/templates
。 -
右键单击
templates
文件夹并选择 从AEM服务器导入: -
重复导入内容的步骤,但选择位于
/conf/wknd-spa-react/settings/wcm/templates/policies
的 策略 文件夹。 -
Inspect位于
ui.content/src/main/content/META-INF/vault/filter.xml
的filter.xml
文件。code language-xml <!--ui.content filter.xml--> <?xml version="1.0" encoding="UTF-8"?> <workspaceFilter version="1.0"> <filter root="/conf/wknd-spa-react" mode="merge"/> <filter root="/content/wknd-spa-react" mode="merge"/> <filter root="/content/dam/wknd-spa-react" mode="merge"/> <filter root="/content/experience-fragments/wknd-spa-react" mode="merge"/> </workspaceFilter>
filter.xml
文件负责识别与包一起安装的节点的路径。 请注意每个筛选器上的mode="merge"
,这表示现有内容将不会被修改,而是只会添加新内容。 由于内容作者可能正在更新这些路径,因此代码部署 不 覆盖内容非常重要。 有关使用筛选器元素的更多详细信息,请参阅FileVault文档。比较
ui.content/src/main/content/META-INF/vault/filter.xml
和ui.apps/src/main/content/META-INF/vault/filter.xml
以了解每个模块管理的不同节点。
(额外练习)创建自定义图像组件 bonus-image
SPA图像组件已由React Core组件提供。 但是,如果您需要额外的练习,请创建自己的映射到AEM 图像组件的React实现。 Image
组件是 content 组件的另一个示例。
Inspect和JSON
在跳转到SPA代码之前,请检查AEM提供的JSON模型。
-
导航到核心组件库🔗中的图像示例。
src
、alt
和title
的属性用于填充SPAImage
组件。note note NOTE 其他公开的图像属性( lazyEnabled
、widths
)允许开发人员创建自适应和延迟加载组件。 本教程中构建的组件非常简单,不 会使用这些高级属性。
实施图像组件
-
接下来,在
ui.frontend/src/components
下创建一个名为Image
的新文件夹。 -
在
Image
文件夹下创建名为Image.js
的新文件。 -
将以下
import
语句添加到Image.js
:code language-js import React, {Component} from 'react'; import {MapTo} from '@adobe/aem-react-editable-components';
-
然后添加
ImageEditConfig
以确定何时在AEM中显示占位符:code language-js export const ImageEditConfig = { emptyLabel: 'Image', isEmpty: function(props) { return !props || !props.src || props.src.trim().length < 1; } };
如果未设置
src
属性,将显示占位符。 -
接下来实施
Image
类:code language-js export default class Image extends Component { get content() { return <img className="Image-src" src={this.props.src} alt={this.props.alt} title={this.props.title ? this.props.title : this.props.alt} />; } render() { if(ImageEditConfig.isEmpty(this.props)) { return null; } return ( <div className="Image"> {this.content} </div> ); } }
上述代码将根据JSON模型传入的prop
src
、alt
和title
呈现<img>
。 -
添加
MapTo
代码以将React组件映射到AEM组件:code language-js MapTo('wknd-spa-react/components/image')(Image, ImageEditConfig);
请注意,字符串
wknd-spa-react/components/image
对应于ui.apps
中AEM组件的位置:ui.apps/src/main/content/jcr_root/apps/wknd-spa-react/components/image
。 -
在同一目录中创建一个名为
Image.css
的新文件并添加以下内容:code language-scss .Image-src { margin: 1rem 0; width: 100%; border: 0; }
-
在
Image.js
中,在import
语句下方的顶部添加对文件的引用:code language-js import React, {Component} from 'react'; import {MapTo} from '@adobe/aem-react-editable-components'; require('./Image.css');
-
打开文件
ui.frontend/src/components/import-components.js
并添加对新Image
组件的引用:code language-js import './Page/Page'; import './Text/Text'; import './Container/Container'; import './ExperienceFragment/ExperienceFragment'; import './Image/Image'; //add reference to Image component
-
在
import-components.js
中注释掉React核心组件图像:code language-js //MapTo('wknd-spa-react/components/image')(ImageV2, {isEmpty: ImageV2IsEmptyFn});
这将确保改用我们的自定义图像组件。
-
使用Maven将SPA代码从项目的根部署到AEM:
code language-shell $ cd aem-guides-wknd-spa.react $ mvn clean install -PautoInstallSinglePackage
-
在AEM中Inspect SPA。 页面上的任何图像组件都应继续工作。 在渲染的输出中Inspect,您应该会看到自定义图像组件(而不是React核心组件)的标记。
自定义图像组件标记
code language-html <div class="Image"> <img class="Image-src" src="/content/image-src.jpg"> </div>
React核心组件图像标记
code language-html <div class="cmp-image cq-dd-image"> <img src="/content/image-src.jpg" class="cmp-image__image"> </div>
这是扩展和实施您自己的组件的良好介绍。