创建自定义组件 custom-component

了解如何创建要与AEM SPA编辑器一起使用的自定义组件。 了解如何开发创作对话框和Sling模型,以扩展JSON模型来填充自定义组件。

目标

  1. 了解Sling模型在操作AEM提供的JSON模型API方面的作用。
  2. 了解如何创建AEM组件对话框。
  3. 了解如何创建 自定义 与AEM编辑器框架兼容的SPA组件。

您将构建的内容

前几章的重点是开发SPA组件并将它们映射到 现有 AEM核心组件。 本章重点介绍如何创建和扩展 新建 AEM组件并处理AEM提供的JSON模型。

简单 Custom Component 说明了创建全新AEM组件所需的步骤。

以全部大写形式显示的消息

前提条件

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

获取代码

  1. 通过Git下载本教程的起点:

    code language-shell
    $ git clone git@github.com:adobe/aem-guides-wknd-spa.git
    $ cd aem-guides-wknd-spa
    $ git checkout Angular/custom-component-start
    
  2. 使用Maven将代码库部署到本地AEM实例:

    code language-shell
    $ mvn clean install -PautoInstallSinglePackage
    

    如果使用 AEM 6.x 添加 classic 个人资料:

    code language-shell
    $ mvn clean install -PautoInstallSinglePackage -Pclassic
    
  3. 为传统安装完成的包 WKND引用站点. 图片提供方: WKND引用站点 在WKND SPA上重用。 可使用以下方式安装软件包 AEM包管理器.

    包管理器安装wknd.all

您始终可以在上查看完成的代码 GitHub 或者切换到分支机构在本地签出代码 Angular/custom-component-solution.

定义AEM组件

AEM组件被定义为节点和属性。 在项目中,这些节点和属性在 ui.apps 模块。 接下来,在中创建AEM组件 ui.apps 模块。

  1. 打开 ui.apps 文件夹。

  2. 导航到 ui.apps/src/main/content/jcr_root/apps/wknd-spa-angular/components 并创建一个名为的文件夹 custom-component.

  3. 创建名为的文件 .content.xmlcustom-component 文件夹。 填充 custom-component/.content.xml ,如下所示:

    code language-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:primaryType="cq:Component"
        jcr:title="Custom Component"
        componentGroup="WKND SPA Angular - Content"/>
    

    创建自定义组件定义

    jcr:primaryType="cq:Component" — 标识此节点是AEM组件。

    jcr:title 是向内容作者显示的值,并且 componentGroup 确定创作UI中的组件分组。

  4. custom-component 创建另一个名为的文件夹 _cq_dialog.

  5. _cq_dialog 文件夹创建名为的文件 .content.xml 并填充以下内容:

    code language-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="Custom Component"
        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}true">
                    <items jcr:primaryType="nt:unstructured">
                        <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">
                                                <message
                                                    jcr:primaryType="nt:unstructured"
                                                    sling:resourceType="granite/ui/components/coral/foundation/form/textfield"
                                                    fieldDescription="The text to display on the component."
                                                    fieldLabel="Message"
                                                    name="./message"/>
                                            </items>
                                        </column>
                                    </items>
                                </columns>
                            </items>
                        </properties>
                    </items>
                </tabs>
            </items>
        </content>
    </jcr:root>
    

    自定义组件定义

    上述XML文件为以下内容生成一个简单的对话框: Custom Component. 文件的关键部分是内部 <message> 节点。 此对话框包含一个 textfield 已命名 Message 并将textifeld的值保留到名为的属性 message.

    随后将创建一个Sling模型以公开 message 属性。

    note note
    NOTE
    您可以查看更多内容 通过查看核心组件定义显示的对话框示例. 您还可以查看其他表单字段,如 selecttextareapathfield,可在下方使用 /libs/granite/ui/components/coral/foundation/formCRXDE-Lite.

    对于传统的AEM组件, HTL 通常需要脚本。 由于SPA呈现组件,因此不需要HTL脚本。

创建Sling模型

Sling模型是注释驱动的Java™“POJO”(纯旧Java™对象),便于将数据从JCR映射到Java™变量。 Sling模型 通常用于为AEM组件封装复杂的服务器端业务逻辑。

在SPA编辑器的上下文中,Sling模型使用功能,通过JSON模型展示组件的内容。 Sling模型导出程序.

  1. 在您选择的IDE中,打开 core 模块。 CustomComponent.javaCustomComponentImpl.java 已在章节启动程序代码中创建和清除。

    note note
    NOTE
    如果使用Visual Studio Code IDE,则安装时可能会有所帮助 Java™扩展.
  2. 打开Java™界面 CustomComponent.javacore/src/main/java/com/adobe/aem/guides/wknd/spa/angular/core/models/CustomComponent.java

    CustomComponent.java接口

    这是由Sling模型实现的Java™接口。

  3. 更新 CustomComponent.java 这样它就扩展了 ComponentExporter 界面:

    code language-java
    package com.adobe.aem.guides.wknd.spa.angular.core.models;
    import com.adobe.cq.export.json.ComponentExporter;
    
    public interface CustomComponent extends ComponentExporter {
    
        public String getMessage();
    
    }
    

    实施 ComponentExporter 接口是Sling模型必须由JSON模型API自动选取的要求。

    CustomComponent 接口包括单个getter方法 getMessage(). 这是通过JSON模型公开作者对话框值的方法。 仅限具有空参数的getter方法 () 将导出为JSON模型。

  4. 打开 CustomComponentImpl.javacore/src/main/java/com/adobe/aem/guides/wknd/spa/angular/core/models/impl/CustomComponentImpl.java.

    这是的实施 CustomComponent 界面。 此 @Model 注释将Java™类标识为Sling模型。 此 @Exporter 注释允许通过Sling模型导出器序列化和导出Java™类。

  5. 更新静态变量 RESOURCE_TYPE 指向AEM组件 wknd-spa-angular/components/custom-component 在上一个练习中创建的。

    code language-java
    static final String RESOURCE_TYPE = "wknd-spa-angular/components/custom-component";
    

    组件的资源类型是将Sling模型绑定到AEM组件并最终映射到Angular组件的类型。

  6. 添加 getExportedType() 方法 CustomComponentImpl 类以返回组件资源类型:

    code language-java
    @Override
    public String getExportedType() {
        return CustomComponentImpl.RESOURCE_TYPE;
    }
    

    实现 ComponentExporter 接口并显示允许映射到Angular组件的资源类型。

  7. 更新 getMessage() 方法返回值 message “创作”对话框保留的属性。 使用 @ValueMap 注释用于映射JCR值 message 到Java™变量:

    code language-java
    import org.apache.commons.lang3.StringUtils;
    ...
    
    @ValueMapValue
    private String message;
    
    @Override
    public String getMessage() {
        return StringUtils.isNotBlank(message) ? message.toUpperCase() : null;
    }
    

    添加了一些附加的“业务逻辑”,以返回消息值作为大写。 这允许我们查看创作对话框存储的原始值与Sling模型公开的值之间的差异。

    note note
    NOTE
    您可以查看 已在此处完成CustomComponentImpl.java.

更新Angular组件

已创建自定义组件的Angular代码。 接下来,进行一些更新以将Angular组件映射到AEM组件。

  1. ui.frontend 模块打开文件 ui.frontend/src/app/components/custom/custom.component.ts

  2. 观察 @Input() message: string; 行。 需要将该转换后的大写值映射到此变量。

  3. 导入 MapTo AEM SPA编辑器JS SDK中的对象,并使用它映射到AEM组件:

    code language-diff
    + import {MapTo} from '@adobe/cq-angular-editable-components';
    
     ...
     export class CustomComponent implements OnInit {
         ...
     }
    
    + MapTo('wknd-spa-angular/components/custom-component')(CustomComponent, CustomEditConfig);
    
  4. 打开 cutom.component.html 并观察到 {{message}} 显示在侧 <h2> 标记之前。

  5. 打开 custom.component.css 并添加以下规则:

    code language-css
    :host-context {
        display: block;
    }
    

    为了在组件为空时正确显示AEM编辑器占位符,请 :host-context 或另一个 <div> 需要设置为 display: block;.

  6. 使用您的Maven技能,从项目目录的根将更新部署到本地AEM环境:

    code language-shell
    $ cd aem-guides-wknd-spa
    $ mvn clean install -PautoInstallSinglePackage
    

更新模板策略

接下来,导航到AEM以验证更新,并允许 Custom Component 添加到SPA中。

  1. 通过导航到“ ”,验证新Sling模型的注册 http://localhost:4502/system/console/status-slingmodels.

    code language-plain
    com.adobe.aem.guides.wknd.spa.angular.core.models.impl.CustomComponentImpl - wknd-spa-angular/components/custom-component
    
    com.adobe.aem.guides.wknd.spa.angular.core.models.impl.CustomComponentImpl exports 'wknd-spa-angular/components/custom-component' with selector 'model' and extension '[Ljava.lang.String;@6fb4a693' with exporter 'jackson'
    

    您应该会看到上面两行表示 CustomComponentImpl 已与 wknd-spa-angular/components/custom-component 组件并通过Sling模型导出器注册。

  2. 导航至SPA页面模板,网址为 http://localhost:4502/editor.html/conf/wknd-spa-angular/settings/wcm/templates/spa-page-template/structure.html.

  3. 更新布局容器的策略以添加新的 Custom Component 作为允许的组件:

    更新布局容器策略

    保存对策略所做的更改,并观察 Custom Component 作为允许的组件:

    将自定义组件作为允许的组件

创作自定义组件

接下来,创作 Custom Component 使用AEM SPA编辑器。

  1. 导航到 http://localhost:4502/editor.html/content/wknd-spa-angular/us/en/home.html.

  2. Edit 模式,添加 Custom ComponentLayout Container

    插入新组件

  3. 打开组件的对话框,然后输入包含一些小写字母的消息。

    配置自定义组件

    这是本章前面基于XML文件创建的对话框。

  4. 保存更改。 请注意,显示的消息全部大写。

    以全部大写形式显示的消息

  5. 导航到,查看JSON模型 http://localhost:4502/content/wknd-spa-angular/us/en.model.json. 搜索 wknd-spa-angular/components/custom-component

    code language-json
    "custom_component_208183317": {
        "message": "HELLO WORLD",
        ":type": "wknd-spa-angular/components/custom-component"
    }
    

    请注意,根据添加到Sling模型的逻辑,JSON值设置为所有大写字母。

恭喜! congratulations

恭喜,您已了解如何创建自定义AEM组件以及Sling模型和对话框如何与JSON模型一起使用。

您始终可以在上查看完成的代码 GitHub 或者切换到分支机构在本地签出代码 Angular/custom-component-solution.

后续步骤 next-steps

扩展核心组件 — 了解如何扩展要与AEM SPA编辑器一起使用的现有核心组件。 了解如何向现有组件添加属性和内容是扩展AEM SPA Editor实施功能的强大技术。

recommendation-more-help
e25b6834-e87f-4ff3-ba56-4cd16cdfdec4