使用AEM元件自訂Adobe使用者端資料層 customize-data-layer
瞭解如何使用自訂Adobe元件的內容來自訂AEM Client Data Layer。 瞭解如何使用AEM核心元件提供的API來擴充和自訂資料層。
您即將建置的內容
在本教學課程中,讓我們透過更新WKND Byline元件,探索擴充Adobe Client Data Layer的各種選項。 Byline元件是自訂元件,在本教學課程中學到的課程可套用至其他自訂元件。
目標 objective
- 透過延伸Sling模型和元件HTL,將元件資料插入資料層
- 使用核心元件資料層公用程式來減少工作量
- 使用核心元件資料屬性以連結至現有的資料層事件
先決條件 prerequisites
需要 本機開發環境 才能完成此教學課程。 熒幕截圖和影片都是使用在macOS上執行的AEM as a Cloud Service SDK擷取。 除非另有說明,否則指令和程式碼與本機作業系統無關。
AEM as a Cloud Service 的新手嗎? 請參閱以下指南以使用 AEM as a Cloud Service SDK 設定本機開發環境。
AEM 6.5 的新手嗎? 請參閱以下指南以設定本機開發環境。
下載及部署WKND參考網站 set-up-wknd-site
本教學課程會擴充WKND參考網站中的Byline元件。 將WKND程式碼基底複製並安裝至您的本機環境。
-
啟動在http://localhost:4502執行的本機Quickstart 作者 AEM執行個體。
-
開啟終端機視窗並使用Git複製WKND程式碼庫:
code language-shell $ git clone git@github.com:adobe/aem-guides-wknd.git -
將WKND程式碼基底部署到AEM的本機執行個體:
code language-shell $ cd aem-guides-wknd $ mvn clean install -PautoInstallSinglePackagenote note NOTE 若為AEM 6.5和最新的Service Pack,請將 classic設定檔新增至Maven命令:mvn clean install -PautoInstallSinglePackage -Pclassic -
開啟新的瀏覽器視窗並登入AEM。 開啟 雜誌 頁面,例如: http://localhost:4502/content/wknd/us/en/magazine/guide-la-skateparks.html。
第
頁上的署名元件
您應該會看到作為體驗片段的一部分新增到頁面的署名元件範例。 您可以在http://localhost:4502/editor.html/content/experience-fragments/wknd/language-masters/en/contributors/stacey-roswells/byline.html檢視體驗片段
-
開啟您的開發人員工具,並在 主控台 中輸入下列命令:
code language-js window.adobeDataLayer.getState();若要檢視AEM網站上資料層的目前狀態,請檢查回應。 您應該會看到頁面和個別元件的相關資訊。
請注意,署名元件並未列於資料層中。
更新署名Sling模型 sling-model
若要在資料層中插入元件的相關資料,請先更新元件的Sling模型。 接下來,更新Byline的Java™介面和Sling模型實作,以使用新方法getData()。 此方法包含要插入資料層的屬性。
-
在您選擇的IDE中開啟
aem-guides-wknd專案。 導覽至core模組。 -
在
core/src/main/java/com/adobe/aem/guides/wknd/core/models/Byline.java開啟檔案Byline.java。
-
將下列方法新增至介面:
code language-java public interface Byline { ... /*** * Return data about the Byline Component to populate the data layer * @return String */ String getData(); } -
在
core/src/main/java/com/adobe/aem/guides/wknd/core/models/impl/BylineImpl.java開啟檔案BylineImpl.java。 這是Byline介面的實作,並且實作為Sling模型。 -
將下列匯入陳述式新增至檔案的開頭:
code language-java import java.util.HashMap; import java.util.Map; import org.apache.sling.api.resource.Resource; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.adobe.cq.wcm.core.components.util.ComponentUtils;fasterxml.jacksonAPI可用來序列化要公開為JSON的資料。 AEM核心元件的ComponentUtils用於檢查資料層是否已啟用。 -
將未實作的方法
getData()新增至BylineImple.java:code language-java public class BylineImpl implements Byline { ... @Override public String getData() { Resource bylineResource = this.request.getResource(); // Use ComponentUtils to verify if the DataLayer is enabled if (ComponentUtils.isDataLayerEnabled(bylineResource)) { //Create a map of properties we want to expose Map<String, Object> bylineProperties = new HashMap<String,Object>(); bylineProperties.put("@type", bylineResource.getResourceType()); bylineProperties.put("name", this.getName()); bylineProperties.put("occupation", this.getOccupations()); bylineProperties.put("fileReference", image.getFileReference()); //Use AEM Core Component utils to get a unique identifier for the Byline component (in case multiple are on the page) String bylineComponentID = ComponentUtils.getId(bylineResource, this.currentPage, this.componentContext); // Return the bylineProperties as a JSON String with a key of the bylineResource's ID try { return String.format("{\"%s\":%s}", bylineComponentID, // Use the ObjectMapper to serialize the bylineProperties to a JSON string new ObjectMapper().writeValueAsString(bylineProperties)); } catch (JsonProcessingException e) { LOGGER.error("Unable to generate dataLayer JSON string", e); } } // return null if the Data Layer is not enabled return null; } }在上述方法中,使用新的
HashMap來擷取要公開為JSON的屬性。 請注意,已使用getName()和getOccupations()等現有方法。@type代表元件的唯一資源型別,它可讓使用者端根據元件的型別輕鬆識別事件和/或觸發器。ObjectMapper可用來序列化屬性並傳回JSON字串。 然後可以將此JSON字串插入資料層中。 -
開啟終端機視窗。 僅使用您的Maven技能建置和部署
core模組:code language-shell $ cd aem-guides-wknd/core $ mvn clean install -PautoInstallBundle
更新署名HTL htl
接下來,更新Byline HTL。 HTL (HTML範本語言)是用來呈現元件HTML的範本。
每個AEM元件上的特殊資料屬性data-cmp-data-layer可用來公開其資料層。 AEM核心元件所提供的JavaScript會尋找此資料屬性。 此資料屬性的值會以Byline Sling模型的getData()方法傳回的JSON字串填入,並插入至Adobe使用者端資料層。
-
在IDE中開啟
aem-guides-wknd專案。 導覽至ui.apps模組。 -
在
ui.apps/src/main/content/jcr_root/apps/wknd/components/byline/byline.html開啟檔案byline.html。
-
更新
byline.html以包含data-cmp-data-layer屬性:code language-diff <div data-sly-use.byline="com.adobe.aem.guides.wknd.core.models.Byline" data-sly-use.placeholderTemplate="core/wcm/components/commons/v1/templates.html" data-sly-test.hasContent="${!byline.empty}" + data-cmp-data-layer="${byline.data}" class="cmp-byline"> ...data-cmp-data-layer的值已設定為"${byline.data}",其中byline是先前更新的Sling模型。.data是呼叫HTL中getData()之Java™ Getter方法的標準標籤法(在上一個練習中實作)。 -
開啟終端機視窗。 僅使用您的Maven技能建置和部署
ui.apps模組:code language-shell $ cd aem-guides-wknd/ui.apps $ mvn clean install -PautoInstallPackage -
返回瀏覽器,然後使用Byline元件重新開啟頁面: http://localhost:4502/content/wknd/us/en/magazine/guide-la-skateparks.html。
-
開啟開發人員工具,並檢查Byline元件頁面的HTML來源:
您應該會看到
data-cmp-data-layer已填入來自Sling模型的JSON字串。 -
開啟瀏覽器的開發人員工具,並在 主控台 中輸入下列命令:
code language-js window.adobeDataLayer.getState(); -
導覽至
component下回應下方,尋找已新增至資料層的byline元件執行個體:
您應該會看到類似以下的專案:
code language-json byline-136073cfcb: @type: "wknd/components/byline" fileReference: "/content/dam/wknd/en/contributors/stacey-roswells.jpg" name: "Stacey Roswells" occupation: (3) ["Artist", "Photographer", "Traveler"] parentId: "page-30d989b3f8"請注意,公開的屬性與Sling模型中
HashMap新增的屬性相同。
新增點選事件 click-event
Adobe Client Data Layer是事件導向,而觸發動作的最常見事件之一是cmp:click事件。 AEM核心元件可透過資料元素data-cmp-clickable輕鬆註冊您的元件。
可點按的元素通常是CTA按鈕或導覽連結。 很遺憾,署名元件沒有這些專案,但我們仍會註冊它,因為這可能適用於其他自訂元件。
-
在IDE中開啟
ui.apps模組 -
在
ui.apps/src/main/content/jcr_root/apps/wknd/components/byline/byline.html開啟檔案byline.html。 -
更新
byline.html以包含Byline的 name 專案上的data-cmp-clickable屬性:code language-diff <h2 class="cmp-byline__name" + data-cmp-clickable="${byline.data ? true : false}"> ${byline.name} </h2> -
開啟新的終端機。 僅使用您的Maven技能建置和部署
ui.apps模組:code language-shell $ cd aem-guides-wknd/ui.apps $ mvn clean install -PautoInstallPackage -
返回瀏覽器,然後使用新增的署名元件重新開啟頁面: http://localhost:4502/content/wknd/us/en/magazine/guide-la-skateparks.html。
為了測試事件,我們將使用開發人員控制檯手動新增一些JavaScript。 如需如何執行此動作的影片,請參閱搭配使用Adobe使用者端資料層與AEM核心元件。
-
開啟瀏覽器的開發人員工具,並在 主控台 中輸入下列方法:
code language-javascript function bylineClickHandler(event) { var dataObject = window.adobeDataLayer.getState(event.eventInfo.path); if (dataObject != null && dataObject['@type'] === 'wknd/components/byline') { console.log("Byline Clicked!"); console.log("Byline name: " + dataObject['name']); } }這個簡單方法應該會處理署名元件名稱的點按。
-
在 主控台 中輸入下列方法:
code language-javascript window.adobeDataLayer.push(function (dl) { dl.addEventListener("cmp:click", bylineClickHandler); });上述方法會將事件接聽程式推送到資料層以接聽
cmp:click事件並呼叫bylineClickHandler。note caution CAUTION 在本練習中,很重要的一點是 不 要重新整理瀏覽器,否則主控台JavaScript會遺失。 -
在瀏覽器中,開啟 主控台 後,按一下Byline元件中的作者名稱:
已按下
您應該會看到主控台訊息
Byline Clicked!和署名名稱。cmp:click事件是最容易連結到的。 如需更複雜的元件及追蹤其他行為,可以新增自訂JavaScript以新增及註冊新事件。 Carousel元件是很好的範例,每當切換幻燈片時會觸發cmp:show事件。 如需更多詳細資料,請參閱原始程式碼。
使用DataLayerBuilder公用程式 data-layer-builder
在本章的早期,當Sling模型已更新時,我們選擇使用HashMap並手動設定每個屬性來建立JSON字串。 此方法適用於小型一次性元件,但若是擴充AEM核心元件的元件,可能會導致大量額外程式碼。
公用程式類別DataLayerBuilder可用來執行大部分的繁重工作。 這允許實作僅擴充其所需的屬性。 讓我們更新Sling模型以使用DataLayerBuilder。
-
返回IDE並導覽至
core模組。 -
在
core/src/main/java/com/adobe/aem/guides/wknd/core/models/Byline.java開啟檔案Byline.java。 -
修改
getData()方法以傳回ComponentData的型別code language-java import com.adobe.cq.wcm.core.components.models.datalayer.ComponentData; ... public interface Byline { ... /*** * Return data about the Byline Component to populate the data layer * @return ComponentData */ ComponentData getData(); }ComponentData是由AEM核心元件提供的物件。 這會產生JSON字串,就像上一個範例一樣,但也會執行許多其他工作。 -
在
core/src/main/java/com/adobe/aem/guides/wknd/core/models/impl/BylineImpl.java開啟檔案BylineImpl.java。 -
新增下列匯入陳述式:
code language-java import com.adobe.cq.wcm.core.components.models.datalayer.ComponentData; import com.adobe.cq.wcm.core.components.models.datalayer.builder.DataLayerBuilder; -
將
getData()方法取代為下列專案:code language-java @Override public ComponentData getData() { Resource bylineResource = this.request.getResource(); // Use ComponentUtils to verify if the DataLayer is enabled if (ComponentUtils.isDataLayerEnabled(bylineResource)) { return DataLayerBuilder.extending(getImage().getData()).asImageComponent() .withTitle(this::getName) .build(); } // return null if the Data Layer is not enabled return null; }「署名」元件會重複使用影像核心元件的部分,以顯示代表作者的影像。 在上述程式碼片段中,DataLayerBuilder是用來擴充
Image元件的資料層。 如此會使用所用影像的所有相關資料預先填入JSON物件。 它也會執行某些常式功能,例如設定@type和元件的唯一識別碼。 請注意,方法很小!唯一一個延伸
withTitle的屬性已被getName()的值取代。 -
開啟終端機視窗。 僅使用您的Maven技能建置和部署
core模組:code language-shell $ cd aem-guides-wknd/core $ mvn clean install -PautoInstallBundle -
返回IDE並開啟
ui.apps下的byline.html檔案 -
更新HTL以使用
byline.data.json填入data-cmp-data-layer屬性:code language-diff <div data-sly-use.byline="com.adobe.aem.guides.wknd.core.models.Byline" data-sly-use.placeholderTemplate="core/wcm/components/commons/v1/templates.html" data-sly-test.hasContent="${!byline.empty}" - data-cmp-data-layer="${byline.data}" + data-cmp-data-layer="${byline.data.json}"請記住,我們現在正在傳回型別
ComponentData的物件。 此物件包含getter方法getJson(),且用來填入data-cmp-data-layer屬性。 -
開啟終端機視窗。 僅使用您的Maven技能建置和部署
ui.apps模組:code language-shell $ cd aem-guides-wknd/ui.apps $ mvn clean install -PautoInstallPackage -
返回瀏覽器,然後使用新增的署名元件重新開啟頁面: http://localhost:4502/content/wknd/us/en/magazine/guide-la-skateparks.html。
-
開啟瀏覽器的開發人員工具,並在 主控台 中輸入下列命令:
code language-js window.adobeDataLayer.getState(); -
瀏覽至
component下回應下方,尋找byline元件的執行個體:
您應該會看到類似以下的專案:
code language-json byline-136073cfcb: @type: "wknd/components/byline" dc:title: "Stacey Roswells" image: @type: "image/jpeg" repo:id: "142658f8-4029-4299-9cd6-51afd52345c0" repo:modifyDate: "2019-10-25T23:49:51Z" repo:path: "/content/dam/wknd/en/contributors/stacey-roswells.jpg" xdm:tags: [] parentId: "page-30d989b3f8" repo:modifyDate: "2019-10-18T20:17:24Z"請注意,
byline元件專案內現在有image物件。 這包含更多有關DAM中資產的資訊。 另請注意,@type和唯一ID (在此例中為byline-136073cfcb)已自動填入,且repo:modifyDate表示元件已修改的時間。
其他範例 additional-examples
-
您可以透過檢查WKND程式碼基底中的
ImageList元件來檢視擴充資料層的另一個範例:ImageList.java-core模組中的Java介面ImageListImpl.java-core模組中的Sling模型。image-list.html-ui.apps模組中的HTL範本。
note note NOTE 使用DataLayerBuilder時,納入 occupation等自訂屬性會比較困難。 不過,如果擴充包含影像或頁面的核心元件,公用程式會節省大量時間。note note NOTE 如果為實作中重複使用的物件建立進階資料層,建議將資料層元素擷取到它們自己的資料層特定Java™物件中。 例如,Commerce核心元件已新增 ProductData和CategoryData的介面,因為這些介面可用於Commerce實作中的許多元件。 如需詳細資訊,請檢閱aem-cif-core-components repo🔗中的程式碼。
恭喜! congratulations
您剛剛探索了幾個方法,可使用AEM元件擴充和自訂Adobe Client Data Layer!