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,轉載請注明原文鏈接:http://www.rzrgm.cn/LinKinSJ/p/17183911.html

浙公網安備 33010602011771號