AEM Adobe experience Manager-扩展核心组件
背景
因为在做一个国际项目,架构师选择AEM进行开发,所以就学了一通。结果在做一个需求的时候遇到一个比较常见问题,就想着输出一篇文档记录一下。
需求背景就是:需要基于WCM(web content management)的核心组件自定义一个面包屑breadcrumb组件。 一般的套路就是自定义组件的.content.xml
配置文件里的sling:resourceSuperType
设置为核心组件的path。但是需求上说需要在原来Breadcrumb组件的Dialog弹窗增加一个textfield 。
需求难点
按上面说的,自定义组件利用resourceSuperType来复用核心组件Breadcrumb,之后再到组件的_cq_dialog的配置里面增加一个textfield的组件。这个配置不难。但是如何利用Sling将新增的textfield通过model返回出来 这个就有点懵了。
解决方式
因为要复用以及扩展组件,所以第一时间想到的就是继承。于是找到了Breadcrumb组件的实现类: BreadcrumbImpl
,想当然的去继承这玩意,但是因为对Sling的原理不太清楚,继承之后增加getText()
方法发现部署上去会报错:can't resolve model...
后来找了个官方文档(见文章最后面的‘参考文章’)
具体实施
上面
ui.apps
是自定义组件的配置项ui.core
是自定义组件model的定义
创建组件
按照上图,创建一个自定义组件,其中breadcrumb组件定义的.content.xml中要设置sling:resourceSuperType="core/wcm/components/breadcrumb/v1/breadcrumb" 指向需要被扩展的核心组件即可,具体配置如下
<?xml version="1.0" encoding="UTF-8"?>
<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:cq="http://www.day.com/jcr/cq/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0"
cq:icon="breadcrumbNavigation"
jcr:description="Displays the position of the current page within the site hierarchy"
sling:resourceSuperType="core/wcm/components/breadcrumb/v1/breadcrumb"
jcr:primaryType="cq:Component"
jcr:title="Breadcrumb Component"
componentGroup="Custom Component"/>
继承/扩展组件Dialog
- 首先在自定义组件中创建_cq_dialog以及对应的.content.xml配置
- 直接在github上复制下breadcrumb的Dialog的.content.xml配置(地址:github-aem-core-wcm-components-breadcrumb
- 进行相应的改造
3.1 使用sling:hideResource="{Boolean}true"
隐藏Dialog原有属性
3.2 新增配置,使用margin="true"
3.3 可以复用的组件就不管,直接添加需要被新增的组件
以下为_cq_dialog详细配置
<?xml version="1.0" encoding="UTF-8"?>
<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:cq="http://www.day.com/jcr/cq/1.0"
xmlns:jcr="http://www.jcp.org/jcr/1.0" xmlns:nt="http://www.jcp.org/jcr/nt/1.0"
jcr:description="Breadcrumb Dialog"
jcr:primaryType="nt:unstructured"
jcr:title="Breadcrumb"
sling:resourceType="cq/gui/components/authoring/dialog"
sling:hideProperties="id"
helpPath="https://www.adobe.com/go/aem_cmp_breadcrumb_v1"
trackingFeature="core-components:breadcrumb:v1">
<content
jcr:primaryType="nt:unstructured"
margin="{Boolean}true"
sling:resourceType="granite/ui/components/coral/foundation/tabs">
<items jcr:primaryType="nt:unstructured">
这里直接隐藏核心组件的fixedColums
<fixedcolums
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/fixedcolumns"
sling:hideResource="{Boolean}true">
</fixedcolums>
这里显示自定义的配置(Dialog上一个叫properties的Tab)
<properties
jcr:primaryType="nt:unstructured"
<!--margin="true" 标识这里可以被扩展-->
margin="true"
sling:resourceType="granite/ui/components/coral/foundation/include"
path="/apps/tech-aem/components/common/breadcrumb/v1/breadcrumb/cq:dialog/properties"/>
</items>
</content>
<properties jcr:primaryType="nt:unstructured"
jcr:title="Properties"
sling:resourceType="granite/ui/components/coral/foundation/container">
<items jcr:primaryType="nt:unstructured">
<fixedcolums
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/fixedcolumns">
<items jcr:primaryType="nt:unstructured">
<properties
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/container">
<items jcr:primaryType="nt:unstructured">
<startLevel
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/form/numberfield"
fieldDescription="The level at which to start the breadcrumb: 0 = /content, 1 = /content/site, etc."
fieldLabel="Navigation Start Level"
max="100"
min="1"
name="./startLevel"
step="1"
value="2"/>
<backgroundColor
jcr:primaryType="nt:unstructured"
name="./backgroundColor"
fieldLabel="Background Color"
sling:resourceType="granite/ui/components/coral/foundation/form/select">
<items jcr:primaryType="nt:unstructured">
<white jcr:primaryType="nt:unstructured"
default="true"
text="White"
value="false"/>
<grey jcr:primaryType="nt:unstructured"
text="Grey"
value="true"/>
</items>
</backgroundColor>
</items>
</properties>
</items>
</fixedcolums>
</items>
</properties>
</jcr:root>
继承/扩展组件Model
上面是前端组件的继承/扩展方式,接下来就是如何扩展核心组件的Model了, 参考下图
- 首先新建一个BreadcrumbModel(interface) 继承 Breadcrumb(interface) 核心组件
- 在BreadcrumbModel中定义新增的方法,这里因为是在dialog里面加了一个textfield,所以新增一个getText()方法
- 创建Sling的Model类:BreadcrumbComponent(类名随便)实现BreadcrumbModel和ComponentExporter这两个interface
- 在BreadcrumbComponent中实现BreadcrumbModel声明的方法
- 增加注解@Model,注意里面的adapters
@Model(adaptables = SlingHttpServletRequest.class,
adapters = {BreadcrumbModel.class, ComponentExporter.class},
resourceType = BreadcrumbComponent.RESOURCE_TYPE, defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL)
@Exporter(name = "jackson", extensions = "json")
public class BreadcrumbComponent implements BreadcrumbModel, ComponentExporter {
// 这里这个很关键,复用就用这个
@Self
@Via(type = ResourceSuperType.class)
private Breadcrumb breadcrumb;
public static final String RESOURCE_TYPE = "tech-aem/components/common/breadcrumb/v1/breadcrumb";
@SlingObject
private SlingHttpServletRequest request;
@ValueMapValue
private String text;
public String getText() {
return text;
}
@Override
public Collection<NavigationItem> getItems() {
return breadcrumb.getItems();
}
}
然后加上package-info.java就大工告成了
结束语
可能会有点啰嗦,所以可以看下官方的文档是怎么个流程
参考文章
本文来自博客园,作者:你啊347,转载请注明原文链接:https://www.cnblogs.com/LinKinSJ/p/17183911.html