这篇文章主要是对AEM前沿技术文档的研究,主要整理了Adobe Experience Management官方文档对于集成SPA框架的各类文档,并加以略微梳理,本篇文章适合有一定AEM开发经验和SPA框架开发经验的人阅读。
这篇文章内容主要是概念性的内容,在对英文文档翻译的过程中,部分深奥的概念我只能借助图来理解,因此翻译可能会有点小出入。读者只需要略微了解即可,下一篇文章将给出AEM集成React框架的完整教程。
简写 | 完整名称 | 简介 |
---|---|---|
SPA | Single-Page Application | 单页应用程序,AEM官方文档解释 英文版 |
MPA | Mulitiple-Page Application | 多页应用程序,比较参考:Ref |
SPA Editor | SPA Editor | 由AEM提供的一层中间库,沟通SPA框架与AEM Editor的桥梁 |
CMS | Content Management System | 内容管理系统 |
WYSIWYG | What You See Is What You Get | 所见即所得 |
WCM | Web Content Management | 网站内容管理 |
SSR | Server-Side Rendering | 服务端渲染 |
MPA和SPA对比
多页应用 | 单页应用 |
---|---|
一个项目中有多个完整的的HTML文件 | 一个项目中只有一个完整的HTML页面(index.html) |
可以使用超链接、js实现页面间的跳转 | 可以使用改进后的超链接、js实现模板页面间的切换 |
传统的页面跳转是同步请求:在服务器生成响应内容时,客户端是一片空白 | 模板页面间的切换属于经典的异步请求:直到下一个模板页面来到,前一个模板页面到来,前一个模板页面才从当前DOM树上删除 |
页面跳转时,前一个DOM树无用了,需要从浏览器中全部删除,然后等待下一个DOM树的到来 | index.html到来时,浏览器创建一个DOM树。所有的请求都是xhr,到来时只需要作为一个片段挂载在当前DOM树——浏览器从始至终只有一个DOM树 |
当网速比较慢时(尤其是移动端应用中时),用户体验极为不好! | 不会出现一片惨白的情形,浏览体验好。 |
页面切换时,DOM被完整的删除,不可能有过场动画! | 页面切换的本质是DIV的轮换,可以很容易实现漂亮的过场动画。 |
详细介绍见:aem-hybrid-architecture-wp-1-18-19.pdf
1)传统CMS架构:
2)典型的无中心式架构:
3)AEM的混合式架构:
1)AEM中的content fragment模型示例:
2)Author编辑CF:
3)创建CF:
4)CF的具体用例:
1)XF在不同设备上的显示变种:
Multichannel content delivery in Experience Manager:简单来说就是应对多种设备的内容交付,如Web端、Mobile端等。
AEM中,主要通过两种形式输出Web Content:HTML和JSON。
1)AEM Sites、Screens、Forms中提供HTMl内容,这里面通过WCM components实现组件化
2)AEM content services framework将内容作为JSON交付,它是在Apache Sling Model Exporter的基础上构建,并为实现其接口的组件提供自己的JSON模式。
Content Services依旧利用了AEM的Templates、Pages、Components,但通过JSON的形式代替了HTML的输出:
HTML交付 vs. JSON交付:
中翻文档 英文文档 本文项目代码
主要内容:
单页应用程序(SPA)与传统页面不同,它在客户端呈现,主要由Javascript驱动,它依赖Ajax调用加载数据和动态更新页面。 大多数或所有内容在单页加载中检索一次,并根据用户与页面的交互情况按需异步加载其他资源。
这减少了页面刷新的需求,并为用户提供了无缝、快速的体验,更像原生的App体验。
AEM SPA编辑器允许前端开发人员创建可集成到AEM站点的SPA,使内容作者能够像编辑任何其他AEM内容一样轻松地编辑SPA内容。
SPA更快、更流畅,更像本机应用程序,它不仅对网页的访客非常有吸引力,而且对营销人员和开发人员也极具吸引力,因为SPA的工作方式。
React
其它信息如Angular相关的可以见以下导航:
文档:
AEM中SPA快速入门——React Getting Started with SPAs in AEM - React
简要总结:
"dependencies": {
"@adobe/cq-react-editable-components": "~1.0.3",
"@adobe/cq-spa-component-mapping": "~1.0.3",
"@adobe/cq-spa-page-model-manager": "~1.0.4"
}
"build": "webpack && clientlib --verbose"
import {MapTo} from '@adobe/cq-react-editable-components';
......
MapTo('my-react-app/components/content/image')(Image, ImageEditConfig);
import React, { Component } from 'react';
import { MapTo } from '@cq/cq-react-editable-components';
...
const EditConfig = {...}
class PageClass extends Component {...};
...
export default MapTo('my-react-app/react/components/structure/page')(PageClass, EditConfig);
import {Page, MapTo, withComponentMappingContext } from "@adobe/cq-react-editable-components";
...
class AppPage extends Page {
...
}
MapTo('my-react-app/components/structure/page')(withComponentMappingContext(AppPage));
import {Page, withModel } from '@adobe/cq-react-editable-components';
...
class App extends Page {
...
}
export default withModel(App);
文档:en cn
源码下载:Github上的We.Retail项目
Weather API Key,可以在官方获取,需要在注册:https://home.openweathermap.org/api_keys
0fb587df6819cb63c0a2cdf9c3f84933
本节摘要:
1)安装依赖:
npm config set registry https://registry.npm.taobao.org
npm install
2)Weather.js分析和注释,注意文档和项目代码有略微不同
//导入依赖模块,ReactWeather来自第三方的开源组件
import React, {Component} from 'react';
import ReactWeather from 'react-open-weather';
import {MapTo} from '@adobe/cq-react-editable-components';
//导入样式
require('./Weather.css');
//通过EditConfig定义城市,检查城市是否为空,若为空,则定义了空值
const WeatherEditConfig = {
emptyLabel: 'Weather',
isEmpty: function(props) {
return !props.city || props.city.trim().length < 1;
}
};
//Weather组件扩展了类 Component 并提供React Open Weather组件的NPM使用文档中定义的所需数据,并渲染该组件。
class Weather extends Component {
render() {
if (this.props.apiKey) {
return <ReactWeather key={'react-weather' + Date.now()}
forecast="today" apikey={this.props.apiKey} type="city" city={this.props.city} />
} else {
return <div className="rw-box weather-error">No api key defined! Weather data cannot be retrieved</div>
}
}
}
//MapTo函数将React组件与相应的AEM组件关联,以便在SPA编辑器中编辑
MapTo('we-retail-journal/components/weather')(Weather, WeatherEditConfig);
文档:cn en
AEM SPA Editor aem-spa-editor.html SPA Editor概述,建议初学者从这开始
SPA Editor SDK Deep Dive - Part 1 - React 深入SPA Editor - React
文档:cn en
简要总结:
SPA框架(React)开始 -> Page Model -> 从Page Editor获取JSON Messaging -> GET请求从Sling Model Exporter获取JSON数据/POST请求Default POST Servlet进行数据更新 -> 获取JCR的资源/后台JCR持久化
几个重要的概念:
SPA Editor的工作流程:
点这里查看动图
SPA Editor更加详细的流程,具体流程描述参考文档:
Authoring的详细工作流程,具体流程文字描述见文档:
文档:cn en
有用内容:
文档:cn en
简介:
PageModelManger
和 ComponentMapping
主要作用就是解释了SPA框架和AEM存储库中的数据的语义的模型结构一般概念:
Page Model,页面模型,用于映射和实例化SPA组件
Meta Fields,元字段,页面模型通过Sling Model API的JSON Model Exporter导出JSON,下列field是导出的用于和底层库交互的数据原型:
:type
:AEM的资源类型(默认等同于resourceType):children
:当前资源的Children子资源(并不是当前资源的inner content,能够在代表Page资源的items中找到):hierarchyType
:资源的层次结构类型,PageModelManager目前仅支持page类型:items
:当前resource的child content,对于嵌套的结构,仅表示表层:itemsOrder
:children的ordered list(排序后的列表),返回的JSON map对象并不能保证所有fields的顺序。通过同时使用Map和当前的array能够使API的消费者具有两者的优点:path
:item的content path,呈现在page resource的items中视频教程: Getting Started with AEM Content Services.
Framework-Specific Module,AEM提供的SPA Editor的NPM特殊包,负责聚合、导出基础modules、services、components,主要包含以下两个NPM libraries
React的实现:npm module: @adobe/cq-react-editable-components
SPA Editor的主要服务和组件(Main Services and Components):
The Model Provider,模型提供者,Project components必须有访问Model Provider的权限,模型提供者必须注册到 [PageModelManager],这样才能为被委托的组件接收、传递更新数据;被委托的组件默认会携带一个叫**“cqModel”**的属性模型。
The Component HTML Decorator,组件的HTML装饰器,负责装饰每个组件实例的元素的外部HTML,并且包含各种Page Editor所需要的data attributes和class names。主要包含:
jcr:content
的Resource路径注意: 每个组件必须扩展当它为空时的占位符功能
Container,容器,是一个包含并渲染子组件的的组件。它主要对Model中的以下属性进行迭代遍历::itemsOrder
、:items
、:children
。
Container能够动态的获取child components(通过 ComponentMapping 库的store),然后,Container使用The Model Provider功能扩展child components,并最终将其实例化。
Page,页面组件,是Container的扩展。文档中的职责描述与Container一样。
Responsive Grid,响应式网格组件,也是一种Container。能够根据模型中的具体类名(class name)对外部HTML动态的装饰。响应式网格组件将预先被映射到与AEM对应的组件,因为其复杂且很少会被自定义。Responsive Grid主要包括:
Specific Model Fields,特定的Model域
Placeholder of the Reponsive Grid,响应式网格的占位符
SPA组件将映射到图形容器(如响应式网格),并且在创作内容时必须添加虚拟子占位符。 当页面编辑器创作SPA内容时,该内容会使用iframe嵌入到编辑器中,并且该属性会 data-cq-editor 添加到该内容的文档节点。 当属 data-cq-editor 性存在时,容器必须包含HTMLElement,以表示将新组件插入页面时作者与之交互的区域。例如:
示例中使用的类名称当前为页面编辑器所必需的。
"new section" : 指示当前元素是容器的占位符
"aem-Grid-newComponent" : 为布局创作规范化组件
Component Mapping,组件映射。
底层的 Component Mapping Library及其函数 MapTo 可以被封装和扩展,为当前component class提供编辑配置相关的功能。
const EditConfig = {//通过EditConfig扩展组件为空时的功能
emptyLabel: 'My Component',
isEmpty: function() {
return !this.props || !this.props.cqModel || this.props.cqModel.isEmpty;
}
};
class MyComponent extends Component {
render() {
return <div className={'my-component'}></div>;
}
}
MapTo('component/resource/path')(MyComponent, EditConfig);
Page Editor的约束配置,project components必须生成如下属性与editor交互:
data-cq-data-path:PageModel提供的组件路径,如:“root/responsivegrid/image”,不应将此属性添加到页面。
要让Page Editor解释组件,project component必须遵守:
举例典型的HTML元素结构:
<div data-cq-data-path="/content/page">
<div class="aem-Grid aem-Grid--12 aem-Grid--default--12">
<div class="aem-container aem-GridColumn aem-GridColumn--default--12" data-cq-data-path="/content/page/jcr:content/root/responsivegrid">
<div class="aem-Grid aem-Grid--12 aem-Grid--default--12">
<div class="cmp-image cq-dd-image aem-GridColumn aem-GridColumn--default--12" data-cq-data-path="/root/responsivegrid/image">
<img src="/content/we-retail-spa-sample/react/jcr%3acontent/root/responsivegrid/image.img.jpeg/1512113734019.jpeg">
div>
div>
div>
div>
div>
响应式网格元素包含前缀为 aem-Grid--
响应式列元素包含前缀为 aem-GridColumn--
响应式网格(也是父网格的列)被封装,例如两个以前的前缀不出现在同一元素上
与可编辑资源对应的元素带有 data-cq-data-path 属性。 请参阅 此文档的“与页面编辑器 ”部分签订合同。
Navigation and Routing,导航和路由。
前端SPA开发需要实现Navigation组件并和AEM的navigation组件映射
文档:cn en
1)Page Model Management的介绍不多说了,见文档。
2)Communication Data Type,通信数据类型,主要通过HTML attribute:data-cq-datatype,指定JSON后,将通过GET请求Sling Model,具体见文档。
3)Meta Properties,元属性
4)Page Editor Overlay Synchronization,编辑器覆盖同步,使用 cq.authoring.page
category
5)Sling Model JSON Exported Structure Configuration
启用路由功能后,假定SPA的JSON导出包含应用程序的不同路由,这要归功于AEM导航组件的JSON导出。 AEM导航组件的JSON输出可以通过以下两个属性在SPA的根页面内容策略中进行配置:
这可以在中的SPA示例内容中显示 /conf/we-retail-journal/react/settings/wcm/policies/we-retail-journal/react/components/structure/page/root 。
文档:cn en
1)ComponentMapping Module,在SPA Blueprint中介绍过了,一个NPM包,映射SPA和AEM的组件,每个model需要有一个 :type
属性,表示AEM的resourceType。SPA组件装载后,将依赖ComponentMapping接收AEM的模型数据来渲染自己。
2)Model-Driven Single Page Application,模型驱动的单页应用程序
3)App Initialization,程序初始化流程,建议看原文图
文档:cn en
1)前端SPA框架自己拥有路由的实现
2)PageModelManager.getData() 的使用,没怎么看懂
3)ModelRouter介绍
4)手动路由和自动路由,示例项目 We.Retail Journal 中React方式是自动路由
5)路由的一些配置约定
文档:cn en
要了解如何将您的SPA与Adobe Experience Platform Launch集成,请参阅此知识库文章和教程 launch-reference-architecture-SPA-tutorial-implement.html,其中将指导您完成Launch设置并实施使用Angular或React构建的Experience Cloud。
文档:cn en
主要就是对AEM中使用SSR的建议和例子,暂不深入。
文档:cn en
以下是AEM SPA Editor SDK(NPM modules)API参考: