HTL Java Use-API

HTL Java Use-API 讓 HTL 檔案能夠存取自訂 Java 類別中的 helper 方法。

使用案例

HTL Java Use-API 讓 HTL 檔案能夠透過 data-sly-use 存取自訂 Java 類別中的 helper 方法。 如此可讓所有複雜的商業邏輯都封裝在 Java 程式碼中,而 HTL 程式碼只需處理直接標記的產生。

Java Use-API 物件可以是簡單 POJO,由特定實作透過 POJO 的預設建構函式具現化。

Use-API POJO 也可以透過以下簽章公開 public 方法 (稱為 init):

    /**
     * Initializes the Use bean.
     *
     * @param bindings All bindings available to the HTL scripts.
     **/
    public void init(javax.script.Bindings bindings);

bindings 對應可以包含一些物件,這些物件為目前執行的 HTL 指令碼提供上下文,以供 Use-API 物件處理之用。

簡單範例

本範例說明 Use-API 的使用情況。

注意

這個範例經過簡化,以利單純說明其用途。 在生產環境中,建議使用 Sling 模型

我們從稱為 info 且沒有 use 類別的 HTL 元件開始。 它是由單一檔案 /apps/my-example/components/info.html 所組成

<div>
    <h1>${properties.title}</h1>
    <p>${properties.description}</p>
</div>

我們也會新增此元件的一些內容,以便在 /content/my-example/ 中呈現:

{
    "sling:resourceType": "my-example/component/info",
    "title": "My Example",
    "description": "This Is Some Example Content."
}

當存取此內容時,就會執行 HTL 檔案。 在 HTL 程式碼中,我們會使用設定語法物件 properties 來存取目前資源的 titledescription 並顯示出來。 輸出檔案 /content/my-example.html 會是:

<div>
    <h1>My Example</h1>
    <p>This Is Some Example Content.</p>
</div>

新增 Use 類別

info 元件目前不需要 use 類別來執行其簡單的函數。但在某些情況下,您需要做一些在 HTL 中無法完成的事,所以需要 use 類別。 但請牢記以下事項:

注意

只有當某件事無法單獨在 HTL 中完成時,才應該使用 use 類別。

例如,假設您希望 info 元件能顯示資源的 titledescription 屬性,但全都以小寫字母顯示。 由於 HTL 沒有方法可顯示小寫字串,所以您需要 use 類別。 我們可以新增 Java use 類別並變更 /apps/my-example/component/info/info.html 來達成此目的,如下所示:

<div data-sly-use.info="Info">
    <h1>${info.lowerCaseTitle}</h1>
    <p>${info.lowerCaseDescription}</p>
</div>

此外,我們也會建立 /apps/my-example/component/info/Info.java

package apps.my_example.components.info;

import com.adobe.cq.sightly.WCMUsePojo;

public class Info extends WCMUsePojo {
    private String lowerCaseTitle;
    private String lowerCaseDescription;

    @Override
    public void activate() throws Exception {
        lowerCaseTitle = getProperties().get("title", "").toLowerCase();
        lowerCaseDescription = getProperties().get("description", "").toLowerCase();
    }

    public String getLowerCaseTitle() {
        return lowerCaseTitle;
    }

    public String getLowerCaseDescription() {
        return lowerCaseDescription;
    }
}

如需詳細資訊,請參閱 com.adobe.cq.sightly.WCMUsePojo 的 Javadocs

現在我們來逐一解說程式碼各個部分。

本機與套件 Java 類別

Java 的 use 類別有兩種安裝方法:

  • 本機 - 在本機安裝中,Java 來源檔案與 HTL 檔案一起放在相同的存放庫資料夾中。來源會自動隨需編譯。 不需要個別的編譯或封裝步驟。
  • 套件 - 在套件安裝中,您必須使用標準 AEM 套件部署機制在 OSGi 套件中編譯及部署 Java 類別 (請參閱「套件式 Java 類別」小節)。

要知道什麼時候使用哪種方法,請記得以下兩個重點:

  • 當 use 類別為此處所討論的元件所專屬時,建議使用​本機 Java use 類別
  • 當 Java 程式碼實作可從多個 HTL 元件存取的服務時,建議使用​套件 Java use 類別

此範例使用本機安裝。

Java 套件是存放庫路徑

當使用本機安裝時,use 類別的封裝名稱必須符合存放庫資料夾位置的名稱,而且路徑中的所有連字號都替換為封裝名稱中的底線。

在此情況下,Info.java 位於 /apps/my-example/components/info,所以封裝為 apps.my_example.components.info

package apps.my_example.components.info;

import com.adobe.cq.sightly.WCMUsePojo;

public class Info extends WCMUsePojo {

   ...

}
注意

AEM 開發中的建議做法是在存放庫項目的名稱中使用連字號。 不過,在 Java 封裝名稱中使用連字號是不合法的。 因此,存放庫路徑中的所有連字號都必須轉換成封裝名稱中的底線

擴充 WCMUsePojo

雖然有許多方法可以將 Java 類別與 HTL 合併 (請參閱「WCMUsePojo 的替代方案」小節),最簡單的方法卻是擴充 WCMUsePojo 類別。例如我們的範例 /apps/my-example/component/info/Info.java

package apps.my_example.components.info;

import com.adobe.cq.sightly.WCMUsePojo;

public class Info extends WCMUsePojo

    ...
}

初始化類別

WCMUsePojo 擴充 use 類別時,覆寫 activate 方法便可以執行初始化,在這個情況下該方法是指 /apps/my-example/component/info/Info.java

...

public class Info extends WCMUsePojo {
    private String lowerCaseTitle;
    private String lowerCaseDescription;

    @Override
    public void activate() throws Exception {
        lowerCaseTitle = getProperties().get("title", "").toLowerCase();
        lowerCaseDescription = getProperties().get("description", "").toLowerCase();
    }

...

}

上下文

通常 activate 方法是用來根據目前上下文 (例如目前的請求和資源) 預先計算及儲存 (在成員變數中) HTL 程式碼中所需的值。

WCMUsePojo 類別允許存取 HTL 檔案中可用的同一組設定語法物件 (請參閱文件「全域物件」)。

在擴充 WCMUsePojo 的類別中,要使用名稱存取設定語法物件時,可使用

<T> T get(String name, Class<T> type)

或者,您也可以利用本表格所列的適當的便利方法,直接存取常用的設定語法物件。

物件 便利方法
PageManager getPageManager()
Page getCurrentPage()
Page getResourcePage()
ValueMap getPageProperties()
ValueMap getProperties()
Designer getDesigner()
Design getCurrentDesign()
Style getCurrentStyle()
Component getComponent()
ValueMap getInheritedProperties()
Resource getResource()
ResourceResolver getResourceResolver()
SlingHttpServletRequest getRequest()
SlingHttpServletResponse getResponse()
SlingScriptHelper getSlingScriptHelper()

Getter 方法

在初始化 use 類別後,就會執行 HTL 檔案。 在這個階段中,HTL 通常會拉入 use 類別的各種成員變數的狀態,並加以呈現。

若要允許從 HTL 檔案內部存取這些值,您必須根據以下命名慣例在 use 類別中定義自訂 getter 方法:

  • 一個採用 getXyz 形式的方法,會在 HTL 檔案中公開一個稱為 xyz 的物件屬性。

在以下範例檔案 /apps/my-example/component/info/Info.java 中,形成物件屬性 titledescriptiongetTitlegetDescription 方法,變成可以在 HTL 檔案的設定語法中存取。

...

public class Info extends WCMUsePojo {

    ...

    public String getLowerCaseTitle() {
        return lowerCaseTitle;
    }

    public String getLowerCaseDescription() {
        return lowerCaseDescription;
    }
}

data-sly-use 屬性

data-sly-use 屬性是用來初始化 HTL 程式碼中的 use 類別。 在我們的範例中,data-sly-use 屬性會宣告我們想要使用 Info 類別。 我們可以僅使用類別的本機名稱,因為我們正在使用本機安裝 (已將 Java 來源檔案放在與 HTL 檔案相同的資料夾中)。 如果我們之前是使用套件安裝,就必須指定完整類別名稱。

請注意這個 /apps/my-example/component/info/info.html 範例的使用情況。

<div data-sly-use.info="Info">
    <h1>${info.lowerCaseTitle}</h1>
    <p>${info.lowerCaseDescription}</p>
</div>

本機識別碼

info 識別碼 (data-sly-use.info 中的點後面的代碼) 會在 HTL 檔案中用來識別類別。 在宣告此識別碼後,其範圍在檔案中為全域, 不限於包含 data-sly-use 陳述式的元素。

請注意這個 /apps/my-example/component/info/info.html 範例的使用情況。

<div data-sly-use.info="Info">
    <h1>${info.lowerCaseTitle}</h1>
    <p>${info.lowerCaseDescription}</p>
</div>

取得屬性

接著會使用識別碼 info 來存取之前透過 getter 方法 Info.getTitleInfo.getDescription 所公開的物件屬性 titledescription

請注意這個 /apps/my-example/component/info/info.html 範例的使用情況。

<div data-sly-use.info="Info">
    <h1>${info.lowerCaseTitle}</h1>
    <p>${info.lowerCaseDescription}</p>
</div>

輸出

現在,當我們存取 /content/my-example.html 時,它會傳回以下 /content/my-example.html 檔案。

<div>
    <h1>my example</h1>
    <p>this is some example content.</p>
</div>
注意

這個範例經過簡化,以利單純說明其用途。在生產環境中,建議使用 Sling 模型

超越基本知識

本節進一步介紹更多功能,比之前敘述的簡單範例更加深入。

  • 傳遞參數給 use 類別
  • 套件式 Java use 類別

傳遞參數

在初始化之後,可以將參數傳遞給 use 類別。 例如,我們可以執行類似以下的操作:

如需詳細資訊,請參閱 Sling HTL Scripting Engine 文件

套件式 Java 類別

使用套件式 use 類別時,必須使用標準 OSGi 套件部署機制在 AEM 中編譯、封裝及部署該類別。與本機安裝不同,use 類別套件宣告應該以一般方式命名,如同此 /apps/my-example/component/info/Info.java 範例。

package org.example.app.components;

import com.adobe.cq.sightly.WCMUsePojo;

public class Info extends WCMUsePojo {
    ...
}

而且 data-sly-use 陳述式必須參照完整類別名稱,而不只是本機類別名稱,如同此 /apps/my-example/component/info/info.html 範例。

<div data-sly-use.info="org.example.app.components.info.Info">
  <h1>${info.title}</h1>
  <p>${info.description}</p>
</div>

本頁內容