建立自訂元件 custom-component

IMPORTANT
新專案中已棄用 SPA 編輯器。Adobe 仍支援現有專案使用此編輯器,但不應用於新專案。目前,AEM 中用於管理 Headless 內容的首選編輯器為:

瞭解如何建立要與AEM SPA Editor搭配使用的自訂元件。 瞭解如何開發作者對話方塊和Sling模型,以擴充JSON模型來填入自訂元件。

目標

  1. 瞭解Sling模型在操控AEM提供的JSON模型API方面的作用。
  2. 瞭解如何建立AEM元件對話方塊。
  3. 瞭解如何建立與SPA編輯器架構相容的​自訂 AEM元件。

您將要建置的內容

前幾章的重點是開發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. Deploy the code base to a local AEM instance using Maven:

    code language-shell
    $ mvn clean install -PautoInstallSinglePackage
    

    If using AEM 6.x add the classic profile:

    code language-shell
    $ mvn clean install -PautoInstallSinglePackage -Pclassic
    
  3. Install the finished package for the traditional WKND reference site. The images provided by WKND reference site are reused on the WKND SPA. The package can be installed using AEM's Package Manager.

    Package Manager install wknd.all

您隨時可以在 GitHub 上檢視完成的程式碼,或透過切換到分支 Angular/custom-component-solution 在本機查看程式碼。

Define the AEM Component

An AEM component is defined as a node and properties. In the project, these nodes and properties are represented as XML files in the ui.apps module. Next, create the AEM component in the ui.apps module.

NOTE
A quick refresher on the basics of AEM components may be helpful.
  1. Open the ui.apps folder in the IDE of your choice.

  2. Navigate to ui.apps/src/main/content/jcr_root/apps/wknd-spa-angular/components and create a folder named custom-component.

  3. Create a file named .content.xml beneath the custom-component folder. Populate the custom-component/.content.xml with the following:

    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"/>
    

    Create Custom Component defintion

    jcr:primaryType="cq:Component" - identifies that this node is an AEM component.

    jcr:title is the value that is displayed to Content Authors and the componentGroup determines the grouping of components in the authoring UI.

  4. Beneath the custom-component folder, create another folder named _cq_dialog.

  5. Beneath the _cq_dialog folder create a file named .content.xml and populate it with the following:

    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>
    

    Custom Component definition

    The above XML file generates a simple dialog for the Custom Component. The critical part of the file is the inner <message> node. This dialog contains a simple textfield named Message and persist the value of the textifeld to a property named message.

    接著會建立Sling模型,以透過JSON模型公開message屬性的值。

    note note
    NOTE
    您可以檢視核心元件定義🔗,以檢視更多對話方塊範例。 您也可以檢視CRXDE-Lite/libs/granite/ui/components/coral/foundation/form下方可用的其他表單欄位,例如selecttextareapathfield

    使用傳統AEM元件時,通常需要HTL指令碼。 由於SPA會轉譯元件,因此不需要HTL指令碼。

建立Sling模型

Sling 模型是由註解驅動的 Java™「POJO」(一般的 Java™ 物件),有助於將 JCR 的資料對應到 Java™ 變數。 Sling模型通常可封裝AEM元件的複雜伺服器端商業邏輯。

在SPA編輯器的內容中,Sling模型使用Sling模型匯出工具,透過JSON模型透過功能公開元件的內容。

  1. 在您選擇的IDE中,開啟core模組。 CustomComponent.javaCustomComponentImpl.java已建立並作為章節起始程式碼的一部分進行存根。

    note note
    NOTE
    如果使用Visual Studio Code IDE,則安裝Java™🔗的擴充功能可能會有幫助。
  2. core/src/main/java/com/adobe/aem/guides/wknd/spa/angular/core/models/CustomComponent.java開啟Java™介面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模型公開作者對話方塊的值。 JSON模型中只會匯出具有空白引數()的getter方法。

  4. core/src/main/java/com/adobe/aem/guides/wknd/spa/angular/core/models/impl/CustomComponentImpl.java開啟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. 從AEM SPA Editor JS SDK匯入MapTo物件,並使用它來對應到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. 請瀏覽至http://localhost:4502/system/console/status-slingmodels,以驗證新Sling模型的註冊。

    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'
    

    您應該會看到以上兩行,指出CustomComponentImplwknd-spa-angular/components/custom-component元件相關聯,並已透過Sling模型匯出工具註冊。

  2. 導覽至http://localhost:4502/editor.html/conf/wknd-spa-angular/settings/wcm/templates/spa-page-template/structure.html的SPA頁面範本。

  3. 更新配置容器的原則以將新的Custom Component新增為允許的元件:

    更新配置容器原則

    儲存原則的變更,並將Custom Component視為允許的元件:

    自訂元件為允許的元件

編寫自訂元件

接下來,使用AEM SPA編輯器編寫Custom Component

  1. 導覽至http://localhost:4502/editor.html/content/wknd-spa-angular/us/en/home.html

  2. Edit模式中,將Custom Component新增至Layout Container

    插入新元件

  3. 開啟元件的對話方塊,然後輸入包含一些小寫字母的訊息。

    設定自訂元件

    這是根據章節中先前的XML檔案建立的對話方塊。

  4. 儲存變更。 請注意,顯示的訊息全部是大寫。

    訊息以全部大寫字顯示

  5. 導覽至http://localhost:4502/content/wknd-spa-angular/us/en.model.json以檢視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 Editor搭配使用的現有核心元件。 瞭解如何將屬性和內容新增至現有元件,是擴充AEM SPA Editor實作功能的強大技術。

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