组件基础知识

在本章中,我们将通过一个简单的HelloWorld示例来探索Adobe Experience Manager(AEM)站点组件的基础技术。 将对现有组件进行小幅修改,涵盖创作、HTL、Sling模型、客户端库等主题。

前提条件

查看设置本地开发环境所需的工具和说明。

视频中使用的IDE是Visual Studio代码VSCode AEM同步插件。

目标

  1. 了解HTL模板和Sling模型在动态渲染HTML方面的作用。
  2. 了解如何使用对话框来促进内容创作。
  3. 了解客户端库的基础知识,以包含用于支持组件的CSS和JavaScript。

将构建的内容

在本章中,您将对非常简单的HelloWorld组件进行几处修改。 在对HelloWorld组件进行更新的过程中,您将了解AEM组件开发的关键方面。

章节入门项目

本章基于由AEM项目原型生成的通用项目。 请观看以下视频并查看先决条件以开始操作!

注意

如果您成功完成了上一章,则可以重复使用该项目并跳过签出起始项目的步骤。

打开新命令行终端并执行以下操作。

  1. 在空目录中,克隆aem-guides-wknd存储库:

    $ git clone git@github.com:adobe/aem-guides-wknd.git --branch tutorial/component-basics-start --single-branch
    
    注意

    或者,您也可以继续使用在上一章项目设置中生成的项目。

  2. 导航到aem-guides-wknd文件夹。

    $ cd aem-guides-wknd
    
  3. 使用以下命令生成项目并将其部署到AEM的本地实例:

    $ mvn clean install -PautoInstallSinglePackage
    
    注意

    如果使用AEM 6.5或6.4,请将classic配置文件附加到任何Maven命令。

    $ mvn clean install -PautoInstallSinglePackage -Pclassic
    
  4. 按照设置本地开发环境的说明,将项目导入首选IDE。

组件创作

组件可以视为网页的小模块化构建块。 要重复使用组件,必须对组件进行配置。 此操作可通过创作对话框完成。 接下来,我们将创作一个简单的组件,并检查对话框中的值是如何在AEM中保留的。

以下是在上述视频中执行的高级步骤。

  1. 在​WKND Site > US > en​下创建名为​组件基础知识​的新页面。
  2. 将​Hello World组件​添加到新创建的页面。
  3. 打开组件的对话框,然后输入一些文本。 保存更改以查看页面上显示的消息。
  4. 切换到开发人员模式,在CRXDE-Lite中查看内容路径,并检查组件实例的属性。
  5. 使用CRXDE-Lite查看位于/apps/wknd/components/content/helloworldcq:dialoghelloworld.html脚本。

HTL(HTML模板语言)和对话框

HTML模板语言或​HTL​是AEM组件用于呈现内容的轻量级服务器端模板语言。

​对话框定义可用于组件的配置。

接下来,我们将更新HelloWorld HTL脚本,以在文本消息之前显示其他问候语。

以下是在上述视频中执行的高级步骤。

  1. 切换到IDE,然后打开ui.apps模块的项目。

  2. 打开helloworld.html文件并更改HTML标记。

  3. 使用诸如VSCode AEM Sync之类的IDE工具,将文件更改与本地AEM实例同步。

  4. 返回到浏览器,并观察组件呈现已更改。

  5. 在以下位置打开用于定义HelloWorld组件对话框的.content.xml文件:

    <code>/aem-guides-wknd/ui.apps/src/main/content/jcr_root/apps/wknd/components/helloworld/_cq_dialog/.content.xml
    
  6. 更新对话框以添加名为​Title​且名称为./title的附加文本字段:

    <?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:primaryType="nt:unstructured"
        jcr:title="Properties"
        sling:resourceType="cq/gui/components/authoring/dialog">
        <content
            jcr:primaryType="nt:unstructured"
            sling:resourceType="granite/ui/components/coral/foundation/fixedcolumns">
            <items jcr:primaryType="nt:unstructured">
                <column
                    jcr:primaryType="nt:unstructured"
                    sling:resourceType="granite/ui/components/coral/foundation/container">
                    <items jcr:primaryType="nt:unstructured">
                        <title
                            jcr:primaryType="nt:unstructured"
                            sling:resourceType="granite/ui/components/coral/foundation/form/textfield"
                            fieldLabel="Title"
                            name="./title"/>
                        <text
                            jcr:primaryType="nt:unstructured"
                            sling:resourceType="granite/ui/components/coral/foundation/form/textfield"
                            fieldLabel="Text"
                            name="./text"/>
                    </items>
                </column>
            </items>
        </content>
    </jcr:root>
    
  7. 重新打开文件helloworld.html,该文件表示负责渲染HelloWorld组件的主HTL脚本,位于:

        <code>/aem-guides-wknd.ui.apps/src/main/content/jcr_root/apps/wknd/components/helloworld/helloworld.html
    
  8. 更新helloworld.html以将​Greeting​文本字段的值呈现为H1标记的一部分:

    <div class="cmp-helloworld" data-cmp-is="helloworld">
        <h1 class="cmp-helloworld__title">${properties.title}</h1>
        ...
    </div>
    
  9. 使用开发人员插件或使用您的Maven技能将更改部署到AEM的本地实例。

Sling 模型

Sling模型是注释驱动的Java“POJO”(纯旧Java对象),它有助于将数据从JCR映射到Java变量,并在AEM上下文中进行开发时提供许多其他细节。

接下来,我们将对HelloWorldModel Sling模型进行一些更新,以便在将某些业务逻辑输出到页面之前,将一些业务逻辑应用于JCR中存储的值。

  1. 打开文件HelloWorldModel.java,该文件是与HelloWorld组件一起使用的Sling模型。

    <code>/aem-guides-wknd.core/src/main/java/com/adobe/aem/guides/wknd/core/models/HelloWorldModel.java
    
  2. 添加以下import语句:

    import org.apache.commons.lang.StringUtils;
    import org.apache.sling.models.annotations.DefaultInjectionStrategy;
    
  3. 更新@Model注释以使用DefaultInjectionStrategy:

    @Model(adaptables = Resource.class,
       defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL)
       public class HelloWorldModel {
       ...
    
  4. 将以下行添加到HelloWorldModel类,以将组件的JCR属性titletext的值映射到Java变量:

    ...
    @Model(adaptables = Resource.class,
    defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL)
    public class HelloWorldModel {
    
        ...
    
        @ValueMapValue
        private String title;
    
        @ValueMapValue
        private String text;
    
        @PostConstruct
        protected void init() {
            ...
    
  5. 将以下方法getTitle()添加到HelloWorldModel类中,该类将返回名为title的属性值。 此方法会添加其他逻辑,以返回字符串值“Default Value here!” 如果属性title为null或为空:

    /***
    *
    * @return the value of title, if null or blank returns "Default Value here!"
    */
    public String getTitle() {
        return StringUtils.isNotBlank(title) ? title : "Default Value here!";
    }
    
  6. 将以下方法getText()添加到HelloWorldModel类中,该类将返回名为text的属性值。 此方法会将字符串转换为所有大写字符。

        /***
        *
        * @return All caps variation of the text value
        */
    public String getText() {
        return StringUtils.isNotBlank(this.text) ? this.text.toUpperCase() : null;
    }
    
  7. core模块构建和部署包:

    $ cd core
    $ mvn clean install -PautoInstallBundle
    
    注意

    如果使用AEM 6.4/6.5,则使用mvn clean install -PautoInstallBundle -Pclassic

  8. 更新位于aem-guides-wknd.ui.apps/src/main/content/jcr_root/apps/wknd/components/content/helloworld/helloworld.html的文件helloworld.html,以使用新创建的HelloWorld模型方法:

    <div class="cmp-helloworld" data-cmp-is="helloworld"
    data-sly-use.model="com.adobe.aem.guides.wknd.core.models.HelloWorldModel">
        <h1 class="cmp-helloworld__title">${model.title}</h1>
        <div class="cmp-helloworld__item" data-sly-test="${properties.text}">
            <p class="cmp-helloworld__item-label">Text property:</p>
            <pre class="cmp-helloworld__item-output" data-cmp-hook-helloworld="property">${properties.text}</pre>
        </div>
        <div class="cmp-helloworld__item" data-sly-test="${model.text}">
            <p class="cmp-helloworld__item-label">Sling Model getText() property:</p>
            <pre class="cmp-helloworld__item-output" data-cmp-hook-helloworld="property">${model.text}</pre>
        </div>
        <div class="cmp-helloworld__item"  data-sly-test="${model.message}">
            <p class="cmp-helloworld__item-label">Model message:</p>
            <pre class="cmp-helloworld__item-output"data-cmp-hook-helloworld="model">${model.message}</pre>
        </div>
    </div>
    
  9. 使用Eclipse Developer插件或使用您的Maven技能将更改部署到AEM的本地实例。

客户端库

客户端库(简称clientlibs)提供了一种机制来组织和管理AEM Sites实施所需的CSS和JavaScript文件。 客户端库是在AEM中在页面上包含CSS和JavaScript的标准方法。

接下来,我们将为HelloWorld组件包含一些CSS样式,以了解客户端库的基本知识。

以下是在上述视频中执行的高级步骤。

  1. /aem-guides-wknd.ui.apps/src/main/content/jcr_root/apps/wknd/clientlibs下方创建一个名为clientlib-helloworld的新文件夹。

  2. clientlibs下创建如下所示的文件夹和文件结构

    /clientlib-helloworld
        /css/helloworld.css
        /js/helloworld.js
        +js.txt
        +css.txt
        +.content.xml
    
  3. 使用以下内容填充helloworld.css :

    .cmp-helloworld .cmp-helloworld__title {
        color: red;
    }
    
  4. 使用以下内容填充helloworld/clientlibs/css.txt :

    #base=css
    helloworld.css
    
  5. 使用以下内容填充helloworld/clientlibs/js/helloworld.js :

    console.log("Hello World from Javascript!");
    
  6. 使用以下内容填充helloworld/clientlibs/js.txt :

    #base=js
    helloworld.js
    
  7. 更新clientlib-helloworld/.content.xml文件以包含以下属性:

    <?xml version="1.0" encoding="UTF-8"?>
    <jcr:root xmlns:cq="http://www.day.com/jcr/cq/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0"
        jcr:primaryType="cq:ClientLibraryFolder"
        allowProxy="{Boolean}true"
        categories="[wknd.helloworld]" />
    
  8. clientlibs/clientlib-base/.content.xml文件更新为​embed​类别wknd.helloworld:

    <?xml version="1.0" encoding="UTF-8"?>
    <jcr:root xmlns:cq="http://www.day.com/jcr/cq/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0"
        jcr:primaryType="cq:ClientLibraryFolder"
        allowProxy="{Boolean}true"
        categories="[wknd.base]"
        embed="[core.wcm.components.accordion.v1,core.wcm.components.tabs.v1,core.wcm.components.carousel.v1,core.wcm.components.image.v2,core.wcm.components.breadcrumb.v2,core.wcm.components.search.v1,core.wcm.components.form.text.v2,core.wcm.components.pdfviewer.v1,core.wcm.components.commons.datalayer.v1,wknd.grid,wknd.helloworld]"/>
    
  9. 使用开发人员插件或使用您的Maven技能将更改部署到AEM的本地实例。

    注意

    出于性能原因,浏览器经常缓存CSS和JavaScript。 如果您没有立即看到客户端库的更改,则执行硬刷新并清除浏览器的缓存。 使用隐身窗口确保新缓存可能会有所帮助。

恭喜!

恭喜,您刚刚学习了Adobe Experience Manager中组件开发的基础知识!

后续步骤

在下一章页面和模板中了解Adobe Experience Manager页面和模板。 了解核心组件如何代理到项目中,并了解可编辑模板的高级策略配置,以构建结构良好的文章页面模板。

GitHub上查看完成的代码,或在Git分支tutorial/component-basics-solution的本地查看并部署代码。

在此页面上