涉及相关
目的
了解如何构建完全自定义的组件。
学习使用Sling模型封装业务逻辑。
了解如何在HTL脚本中使用Sling模型。
效果
开始创造
这个新组件的实现包括一个对话框,该对话框收集副标题内容,并且自定义Sling模型动态检索副标题的
名称
图片
职业
创建Byline组件
首先,创建Byline组件节点结构并定义一个对话框。这表示AEM中的组件,并通过其在JCR中的位置隐式定义了组件的资源类型。
该对话框显示内容作者可以提供的界面。对于此实现,将利用AEM WCM核心组件的 Image 组件来处理Byline图像的创作和渲染,因此将其设置为组件的 sling:resourceSuperType
创建组件节点
1、在 UI .apps 模块下方 /apps/wknd/components/content 创建名为byline 类型的 cq:Component 的新节点 。
.content.xml 节点属性文件内容如下:
<?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"
jcr:description="Displays a contributor's byline."
jcr:primaryType="cq:Component"
jcr:title="Byline"
sling:resourceSuperType="core/wcm/components/image/v2/image"
componentGroup="WKND.Content"/>
创建HTL脚本
1、下面的 byline 节点,添加的文件名为 byline.html 负责组件的HTML呈现。将文件命名为与 cq:Component节点相同很重要,因为这使它成为Sling用来呈现此资源类型的默认脚本。
2、将以下代码添加到 byline.html中
<!--/* byline.html */-->
<div data-sly-use.placeholderTemplate="core/wcm/components/commons/v1/templates.html">
</div>
<sly data-sly-call="${placeholderTemplate.placeholder @ isEmpty=true}"></sly>
一旦创建了Sling模型,便会再次访问byline.html 。HTL文件的当前状态允许组件在拖放到页面上时在AEM站点的页面编辑器中显示。
创建对话框定义
接下来,使用以下字段为Byline组件定义一个对话框:
Name :名字
Image :头像
Occupations :职业列表。应按字母升序(a到z)对职业进行排序。
1、在 byline 组件节点下,创建一个名为cq:dialog 的新节点 ,类型为 nt:unstructured ;
2、使用以下XML 更新 cq:dialog 。打开.content.xml 并将以下XML复制/粘贴到其中
<?xml version="1.0" encoding="UTF-8"?>
<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:granite="http://www.adobe.com/jcr/granite/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:primaryType="nt:unstructured"
jcr:title="Byline"
sling:resourceType="cq/gui/components/authoring/dialog">
<content
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/container">
<items jcr:primaryType="nt:unstructured">
<tabs
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/tabs"
maximized="{Boolean}false">
<items jcr:primaryType="nt:unstructured">
<!-- This allows the Core Components' Image component's asset definition tab -->
<asset
jcr:primaryType="nt:unstructured"
sling:hideResource="{Boolean}false"/>
<!-- This hides the Core Components' Image component's metadata tab -->
<metadata
jcr:primaryType="nt:unstructured"
sling:hideResource="{Boolean}true"/>
<properties
jcr:primaryType="nt:unstructured"
jcr:title="Properties"
sling:resourceType="granite/ui/components/coral/foundation/container"
margin="{Boolean}true">
<items jcr:primaryType="nt:unstructured">
<columns
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/fixedcolumns"
margin="{Boolean}true">
<items jcr:primaryType="nt:unstructured">
<column
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/container">
<items jcr:primaryType="nt:unstructured">
<name
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/form/textfield"
fieldLabel="Name"
fieldDescription="The contributor's name to display."
emptyText="Enter the contributor's name to display." name="./name"
required="{Boolean}true"/>
<occupations
jcr:primaryType="nt:unstructured"
fieldLabel="Occupations"
fieldDescription="A list of the contributor's occupations."
required="{Boolean}false"
sling:resourceType="granite/ui/components/coral/foundation/form/multifield">
<field
jcr:primaryType="nt:unstructured"
name="./occupations"
emptyText="Enter an occupation"
sling:resourceType="granite/ui/components/coral/foundation/form/textfield"/>
</occupations>
</items>
</column>
</items>
</columns>
</items>
</properties>
</items>
</tabs>
</items>
</content>
</jcr:root>
创建策略对话框
遵循与创建对话框相同的方法,创建“策略”对话框(以前称为“设计对话框”),以隐藏从核心组件的图像组件继承的策略配置中不需要的字段。
1、在 byline cq:Component 节点下,创建一个名为cq:design_dialog的新节点 ,类型为nt:unstructured
2、使用以下XML 更新 cq:design_dialog 。打开.content.xml 并将下面的XML复制/粘贴到其中是最容易的
<?xml version="1.0" encoding="UTF-8"?>
<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0"
xmlns:nt="http://www.jcp.org/jcr/nt/1.0" xmlns:cq="http://www.day.com/jcr/cq/1.0"
xmlns:granite="http://www.adobe.com/jcr/granite/1.0"
jcr:primaryType="nt:unstructured"
jcr:title="Byline"
sling:resourceType="cq/gui/components/authoring/dialog">
<content
jcr:primaryType="nt:unstructured">
<items jcr:primaryType="nt:unstructured">
<tabs
jcr:primaryType="nt:unstructured">
<items jcr:primaryType="nt:unstructured">
<properties
jcr:primaryType="nt:unstructured">
<items jcr:primaryType="nt:unstructured">
<content
jcr:primaryType="nt:unstructured">
<items jcr:primaryType="nt:unstructured">
<decorative
jcr:primaryType="nt:unstructured"
sling:hideResource="{Boolean}true"/>
<altValueFromDAM
jcr:primaryType="nt:unstructured"
sling:hideResource="{Boolean}true"/>
<titleValueFromDAM
jcr:primaryType="nt:unstructured"
sling:hideResource="{Boolean}true"/>
<displayCaptionPopup
jcr:primaryType="nt:unstructured"
sling:hideResource="{Boolean}true"/>
<disableUuidTracking
jcr:primaryType="nt:unstructured"
sling:hideResource="{Boolean}true"/>
</items>
</content>
</items>
</properties>
<features
jcr:primaryType="nt:unstructured">
<items jcr:primaryType="nt:unstructured">
<content
jcr:primaryType="nt:unstructured">
<items jcr:primaryType="nt:unstructured">
<accordion
jcr:primaryType="nt:unstructured">
<items jcr:primaryType="nt:unstructured">
<orientation
jcr:primaryType="nt:unstructured"
sling:hideResource="{Boolean}true"/>
<crop
jcr:primaryType="nt:unstructured"
sling:hideResource="{Boolean}true"/>
</items>
</accordion>
</items>
</content>
</items>
</features>
</items>
</tabs>
</items>
</content>
</jcr:root>
创建Byline Sling模型
Sling模型以充当数据模型并容纳Byline组件的业务逻辑。
Sling模型是注释驱动的Java“ POJO”(普通的旧Java对象),它有助于将数据从JCR映射到Java变量
更新pom.xml 文件
1、打开父POM: aem -guides-wknd / pom.xml
2、确保 uber-jar 依赖性为 6.3.2 或更高。
<!-- Adobe AEM Dependencies -->
<dependency>
<groupId>com.adobe.aem</groupId>
<artifactId>uber-jar</artifactId>
<version>6.4.5</version>
<classifier>apis</classifier>
<scope>provided</scope>
</dependency>
3、在父POM中,为Core Components 添加依赖项 。这是与核心组件关联的Sling模型的依赖项。core.wcm.components.all 、core.wcm.components.core
4、完整的父 POM.XML
<?xml version="1.0" encoding="UTF-8"?>
<!--
| Copyright 2015 Adobe Systems Incorporated
|
| Licensed under the Apache License, Version 2.0 (the "License");
| you may not use this file except in compliance with the License.
| You may obtain a copy of the License at
|
| http://www.apache.org/licenses/LICENSE-2.0
|
| Unless required by applicable law or agreed to in writing, software
| distributed under the License is distributed on an "AS IS" BASIS,
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
| See the License for the specific language governing permissions and
| limitations under the License.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.adobe.aem.guides</groupId>
<artifactId>aem-guides-wknd</artifactId>
<packaging>pom</packaging>
<version>0.0.1-SNAPSHOT</version>
<description>WKND Sites Project</description>
<modules>
<module>core</module>
<module>ui.apps</module>
<module>ui.content</module>
<module>it.tests</module>
<module>it.launcher</module>
</modules>
<properties>
<aem.host>localhost</aem.host>
<aem.port>4502</aem.port>
<aem.publish.host>localhost</aem.publish.host>
<aem.publish.port>4503</aem.publish.port>
<sling.user>admin</sling.user>
<sling.password>admin</sling.password>
<vault.user>admin</vault.user>
<vault.password>admin</vault.password>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
</properties>
<build>
<plugins>
<!-- Maven Release Plugin -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-release-plugin</artifactId>
<version>2.5.3</version>
<configuration>
<scmCommentPrefix>[maven-scm] :</scmCommentPrefix>
<preparationGoals>clean install</preparationGoals>
<goals>install</goals>
<releaseProfiles>release</releaseProfiles>
</configuration>
</plugin>
<!-- Maven Source Plugin -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>3.0.1</version>
<inherited>true</inherited>
</plugin>
<!-- Maven Jar Plugin -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.0.2</version>
</plugin>
<!-- Maven Enforcer Plugin -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<executions>
<execution>
<id>enforce-maven</id>
<goals>
<goal>enforce</goal>
</goals>
<configuration>
<rules>
<requireMavenVersion>
<version>[3.3.9,)</version>
</requireMavenVersion>
<requireJavaVersion>
<message>Project must be compiled
with Java 8 or higher</message>
<version>1.8.0</version>
</requireJavaVersion>
</rules>
</configuration>
</execution>
</executions>
</plugin>
<!-- Maven Compiler Plugin -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<!-- Maven IntelliJ IDEA Plugin -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-idea-plugin</artifactId>
<version>2.2.1</version>
<configuration>
<jdkLevel>1.8</jdkLevel>
<linkModules>true</linkModules>
<downloadSources>true</downloadSources>
</configuration>
</plugin>
<!-- Maven Eclipse Plugin -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-eclipse-plugin</artifactId>
<version>2.10</version>
<configuration>
<downloadSources>true</downloadSources>
</configuration>
</plugin>
</plugins>
<pluginManagement>
<plugins>
<!-- Maven Clean Plugin -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-clean-plugin</artifactId>
<version>3.0.0</version>
</plugin>
<!-- Maven Resources Plugin -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>3.0.2</version>
</plugin>
<!-- Maven Compiler Plugin -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.6.1</version>
</plugin>
<!-- Maven Installer Plugin -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-install-plugin</artifactId>
<version>2.5.2</version>
</plugin>
<!-- Maven Surefire Plugin -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.1</version>
<configuration>
<useSystemClassLoader>false</useSystemClassLoader>
</configuration>
</plugin>
<!-- Maven Failsafe Plugin -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.22.1</version>
</plugin>
<!-- Maven Deploy Plugin -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.8.2</version>
</plugin>
<!-- Apache Sling Plugin -->
<plugin>
<groupId>org.apache.sling</groupId>
<artifactId>maven-sling-plugin</artifactId>
<version>2.2.0</version>
<configuration>
<slingUrl>http://${aem.host}:${aem.port}/system/console</slingUrl>
<deploymentMethod>WebConsole</deploymentMethod>
</configuration>
</plugin>
<!-- HTL Maven Plugin -->
<plugin>
<groupId>org.apache.sling</groupId>
<artifactId>htl-maven-plugin</artifactId>
<version>1.0.6</version>
<configuration>
<failOnWarnings>true</failOnWarnings>
</configuration>
<executions>
<execution>
<goals>
<goal>validate</goal>
</goals>
</execution>
</executions>
</plugin>
<!-- Jackrabbit FileVault Package Plugin -->
<plugin>
<groupId>org.apache.jackrabbit</groupId>
<artifactId>filevault-package-maven-plugin</artifactId>
<version>1.0.3</version>
<configuration>
<filterSource>src/main/content/META-INF/vault/filter.xml</filterSource>
</configuration>
</plugin>
<!-- Content Package Plugin -->
<plugin>
<groupId>com.day.jcr.vault</groupId>
<artifactId>content-package-maven-plugin</artifactId>
<version>1.0.2</version>
<configuration>
<targetURL>http://${aem.host}:${aem.port}/crx/packmgr/service.jsp</targetURL>
<failOnError>true</failOnError>
<userId>${vault.user}</userId>
<password>${vault.password}</password>
</configuration>
</plugin>
<!-- Apache Felix Bundle Plugin -->
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<version>4.2.1</version>
<inherited>true</inherited>
</plugin>
<!-- Maven Enforcer Plugin -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<version>1.4.1</version>
</plugin>
<!-- Maven Dependency Plugin -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>3.0.0</version>
</plugin>
<!-- Build Helper Maven Plugin -->
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>3.0.0</version>
</plugin>
<!--This plugin's configuration is used to store Eclipse
m2e settings only. It has no influence on the Maven build itself. -->
<plugin>
<groupId>org.eclipse.m2e</groupId>
<artifactId>lifecycle-mapping</artifactId>
<version>1.0.0</version>
<configuration>
<lifecycleMappingMetadata>
<pluginExecutions>
<pluginExecution>
<pluginExecutionFilter>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<versionRange>[1.0.0,)</versionRange>
<goals>
<goal>enforce</goal>
</goals>
</pluginExecutionFilter>
<action>
<ignore />
</action>
</pluginExecution>
<pluginExecution>
<pluginExecutionFilter>
<groupId>
org.apache.maven.plugins
</groupId>
<artifactId>
maven-dependency-plugin
</artifactId>
<versionRange>
[2.2,)
</versionRange>
<goals>
<goal>copy-dependencies</goal>
<goal>unpack</goal>
</goals>
</pluginExecutionFilter>
<action>
<ignore />
</action>
</pluginExecution>
<pluginExecution>
<pluginExecutionFilter>
<groupId>
org.codehaus.mojo
</groupId>
<artifactId>
build-helper-maven-plugin
</artifactId>
<versionRange>
[1.5,)
</versionRange>
<goals>
<goal>
reserve-network-port
</goal>
</goals>
</pluginExecutionFilter>
<action>
<ignore />
</action>
</pluginExecution>
</pluginExecutions>
</lifecycleMappingMetadata>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
<profiles>
<!-- ====================================================== -->
<!-- A D O B E P U B L I C P R O F I L E -->
<!-- ====================================================== -->
<profile>
<id>adobe-public</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<releaseRepository-Id>adobe-public-releases</releaseRepository-Id>
<releaseRepository-Name>Adobe Public Releases</releaseRepository-Name>
<releaseRepository-URL>https://repo.adobe.com/nexus/content/groups/public</releaseRepository-URL>
</properties>
<repositories>
<repository>
<id>adobe-public-releases</id>
<name>Adobe Public Repository</name>
<url>https://repo.adobe.com/nexus/content/groups/public</url>
<releases>
<enabled>true</enabled>
<updatePolicy>never</updatePolicy>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>adobe-public-releases</id>
<name>Adobe Public Repository</name>
<url>https://repo.adobe.com/nexus/content/groups/public</url>
<releases>
<enabled>true</enabled>
<updatePolicy>never</updatePolicy>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
</profile>
<!-- Development profile: install only the bundle -->
<profile>
<id>autoInstallBundle</id>
<!--
To enable this feature for a bundle, the maven-sling-plugin
(without configuration) needs to be included:
<plugin>
<groupId>org.apache.sling</groupId>
<artifactId>maven-sling-plugin</artifactId>
</plugin>
-->
<activation>
<activeByDefault>false</activeByDefault>
</activation>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.sling</groupId>
<artifactId>maven-sling-plugin</artifactId>
<executions>
<execution>
<id>install-bundle</id>
<goals>
<goal>install</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</pluginManagement>
</build>
</profile>
<profile>
<id>autoInstallPackage</id>
<activation>
<activeByDefault>false</activeByDefault>
</activation>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.jackrabbit</groupId>
<artifactId>filevault-package-maven-plugin</artifactId>
<executions>
<execution>
<id>create-package</id>
<goals>
<goal>package</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>com.day.jcr.vault</groupId>
<artifactId>content-package-maven-plugin</artifactId>
<executions>
<execution>
<id>install-package</id>
<goals>
<goal>install</goal>
</goals>
<configuration>
<targetURL>http://${aem.host}:${aem.port}/crx/packmgr/service.jsp</targetURL>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</pluginManagement>
</build>
</profile>
<profile>
<id>autoInstallPackagePublish</id>
<activation>
<activeByDefault>false</activeByDefault>
</activation>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.jackrabbit</groupId>
<artifactId>filevault-package-maven-plugin</artifactId>
<executions>
<execution>
<id>create-package</id>
<goals>
<goal>package</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>com.day.jcr.vault</groupId>
<artifactId>content-package-maven-plugin</artifactId>
<executions>
<execution>
<id>install-package-publish</id>
<goals>
<goal>install</goal>
</goals>
<configuration>
<targetURL>http://${aem.publish.host}:${aem.publish.port}/crx/packmgr/service.jsp</targetURL>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</pluginManagement>
</build>
</profile>
</profiles>
<!-- ====================================================================== -->
<!-- D E P E N D E N C I E S -->
<!-- ====================================================================== -->
<dependencyManagement>
<dependencies>
<!-- OSGi Dependencies -->
<dependency>
<groupId>org.osgi</groupId>
<artifactId>osgi.core</artifactId>
<version>6.0.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.osgi</groupId>
<artifactId>osgi.cmpn</artifactId>
<version>6.0.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.osgi</groupId>
<artifactId>osgi.annotation</artifactId>
<version>6.0.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<version>1</version>
</dependency>
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
<version>1.3.2</version>
<scope>provided</scope>
</dependency>
<!-- Logging Dependencies -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.21</version>
<scope>provided</scope>
</dependency>
<!-- Adobe AEM Dependencies -->
<dependency>
<groupId>com.adobe.aem</groupId>
<artifactId>uber-jar</artifactId>
<version>6.4.5</version>
<classifier>apis</classifier>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.adobe.cq</groupId>
<artifactId>core.wcm.components.all</artifactId>
<type>zip</type>
<version>2.3.2</version>
</dependency>
<dependency>
<groupId>com.adobe.cq</groupId>
<artifactId>core.wcm.components.examples</artifactId>
<type>zip</type>
<version>2.3.2</version>
</dependency>
<dependency>
<groupId>com.adobe.cq</groupId>
<artifactId>core.wcm.components.core</artifactId>
<version>2.2.0</version>
<scope>provided</scope>
</dependency>
<!-- Apache Sling Dependencies -->
<dependency>
<groupId>org.apache.sling</groupId>
<artifactId>org.apache.sling.models.api</artifactId>
<version>1.3.6</version>
<scope>provided</scope>
</dependency>
<!-- Servlet API -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.1</version>
<scope>provided</scope>
</dependency>
<!-- JCR -->
<dependency>
<groupId>javax.jcr</groupId>
<artifactId>jcr</artifactId>
<version>2.0</version>
<scope>provided</scope>
</dependency>
<!-- Taglibs -->
<dependency>
<groupId>com.day.cq.wcm</groupId>
<artifactId>cq-wcm-taglib</artifactId>
<version>5.7.4</version>
<scope>provided</scope>
</dependency>
<!-- Testing -->
<dependency>
<groupId>org.junit</groupId>
<artifactId>junit-bom</artifactId>
<version>5.4.1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.7.25</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>2.25.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-junit-jupiter</artifactId>
<version>2.25.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit-addons</groupId>
<artifactId>junit-addons</artifactId>
<version>1.4</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.wcm</groupId>
<artifactId>io.wcm.testing.aem-mock.junit5</artifactId>
<version>2.4.4</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>uk.org.lidalia</groupId>
<artifactId>slf4j-test</artifactId>
<version>1.0.1</version>
<scope>test</scope>
</dependency>
</dependencies>
</dependencyManagement>
</project>
Byline组件对应的接口
1、为Byline创建一个公共Java接口,Byline.java 定义驱动byline.html HTL脚本所需的公共方法
2、在src / main / java下面的 aem-guides-wknd.core 模块中创建一个名为com.adobe.aem.guides.wknd.core.components 的新Java包
3、com.adobe.aem.guides.wknd.core.components 创建一个名为Byline.java 的新Java 接口
package com.adobe.aem.guides.wknd.core.components;
import java.util.List;
/**
* 代表WKND Site项目的Byline AEM组件
*
* @author kevin
* @title: Byline
* @projectName aem-guides-wknd
* @date 2019/10/1614:35
*/
public interface Byline {
/***
* @return 返回字符串以显示为名称.
*/
String getName();
/***
* 职业将按字母降序排列.
*
* @return 返回职业列表.
*/
List<String> getOccupations();
/***
* @return 返回布尔值(如果组件具有要显示的内容).
*/
boolean isEmpty();
}
创建Byline.java 的实现类BylineImpl.java
1、com.adobe.aem.guides.wknd.core.components.impl包下创建BylineImpl.java
2、通过使用以下类级别的注释更新BylineImpl.java来 添加Sling Model 注释。此 @Model(…)批注将把 类变成Sling模型
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.models.annotations.Model;
import org.apache.sling.models.annotations.DefaultInjectionStrategy;
...
@Model(
adaptables = {SlingHttpServletRequest.class},
adapters = {Byline.class},
resourceType = {BylineImpl.RESOURCE_TYPE},
defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL
)
public class BylineImpl implements Byline {
protected static final String RESOURCE_TYPE = "wknd/components/content/byline";
...
}
说明:
@Model : 声明为Sling模型
adaptables = {SlingHttpServletRequest.class}: 作用是:将sling模型映射到sling资源上(此模型可以由请求)
resourceType = {BylineImpl.RESOURCE_TYPE} : 指向署名组件的资源类型
defaultInjectionStrategy : 指示sling模型中的注入字段是否应该是必需的/可选的
3、完整代码
package com.adobe.aem.guides.wknd.core.components.impl;
import com.adobe.aem.guides.wknd.core.components.Byline;
import com.adobe.cq.wcm.core.components.models.Image;
import java.util.Collections;
import java.util.List;
import javax.annotation.PostConstruct;
import org.apache.commons.lang3.StringUtils;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.models.annotations.DefaultInjectionStrategy;
import org.apache.sling.models.annotations.Model;
import org.apache.sling.models.annotations.injectorspecific.OSGiService;
import org.apache.sling.models.annotations.injectorspecific.Self;
import org.apache.sling.models.annotations.injectorspecific.ValueMapValue;
import org.apache.sling.models.factory.ModelFactory;
/**
* todo
*
* @author kevin
* @title: BylineImpl
* @projectName aem-guides-wknd
* @date 2019/10/1614:39
*/
@Model(adaptables = {SlingHttpServletRequest.class},
adapters = {Byline.class},
resourceType = {BylineImpl.RESOURCE_TYPE},
defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL)
public class BylineImpl implements Byline {
/** 资源类型 **/
protected static final String RESOURCE_TYPE = "wknd/components/content/byline";
@ValueMapValue //注入属性
private String name;
@ValueMapValue //注入属性
//@Named("fullName") 指定名称注入
private List<String> occupations;
@OSGiService //注入模型工厂
private ModelFactory modelFactory;
@Self //向字段注入可适应的对象获取请求上下文
private SlingHttpServletRequest request;
//@Self 直接注入image.class资源
private Image image;
@PostConstruct //实例化
private void init() {
image = modelFactory.getModelFromWrappedRequest(request, request.getResource(), Image.class);
}
/***
* @return a string to display as the name.
*/
@Override
public String getName() {
return name;
}
/***
* Occupations are to be sorted alphabetically in a descending order.
*
* @return a list of occupations.
*/
@Override
public List<String> getOccupations() {
if (occupations != null) {
Collections.sort(occupations);
return occupations;
} else {
return Collections.emptyList();
}
}
/***
* @return a boolean if the component has content to display.
*/
@Override
public boolean isEmpty() {
if (StringUtils.isBlank(name)) {
// Name is missing, but required
return true;
} else if (occupations == null || occupations.isEmpty()) {
// At least one occupation is required
return true;
} else if (getImage() == null || StringUtils.isBlank(getImage().getSrc())) {
// A valid image is required
return true;
} else {
// Everything is populated, so this component is not considered empty
return false;
}
}
private Image getImage() {
Image image = null;
// Figure out how to populate the image variable!
return image;
}
}
修改 byline.html 完整代码如下
<div data-sly-use.byline ="com.adobe.aem.guides.wknd.core.components.Byline"
data-sly-use.placeholderTemplate="core/wcm/components/commons/v1/templates.html"
data-sly-test.hasContent = "${byline.empty}"
class="cmp-byline">
<div class="cmp-byline__image"
data-sly-resource="${ '.' @ resourceType = 'core/wcm/components/image/v2/image' }">
<!-- Include the Core Components Image Component -->
</div>
<h2 class="cmp-byline__name">${byline.name}</h2>
<p class="cmp-byline__occupations">${byline.occupations @ join='|'}</p>
</div>
<sly data-sly-call="${placeholderTemplate.placeholder @ isEmpty= !hasContent}"></sly>
data-sly-use.byline ="com.adobe.aem.guides.wknd.core.components.Byline
引入 Byline Sling模型,后面就可以直接调用公共方法了
将代码库部署到本地AEM实例
部署成功status是active
如果状态不是active点击名称展开,检查是否有标红错误
1、如果有错误,根据错误进行解决
2、错误原因大概分为,jar包缺失,jar包冲突,jar版本错误
到此组件创建完成可以开始使用了
使用组件
1、在模板创建,表单和碎片创建处均可以使用改组件
2、从左侧拖到组件到右边即可使用
3、编辑组件数据