HTL Java Use-API htl-java-use-api

HTL Java Use-API を使用すると、HTL ファイルからカスタム Java クラスのヘルパーメソッドへのアクセスが可能になります。

ユースケース use-case

HTL Java Use-API を使用すると、HTL ファイルは data-sly-use を通してカスタム Java クラスのヘルパーメソッドへのアクセスが可能になります。このメソッドにより、複雑なビジネスロジックをすべて Java コードでカプセル化し、HTL コードではマークアップの直接作成処理のみを行うことができます。

Java Use-API オブジェクトは、POJO のデフォルトのコンストラクタを通じて、特定の実装でインスタンス化された単純な POJO にすることができます。

Use-API POJO は、次のシグネチャを持つ init と呼ばれるパブリックメソッドも公開できます。

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

bindings マップには、Use-API オブジェクトが処理に使用できる、現在実行されている HTL スクリプトにコンテキストを提供するオブジェクトを含めることができます。

簡単な例 a-simple-example

この例では、Use-API の使用方法を説明します。

NOTE
この例は、その使用方法を説明するために簡略化しています。実稼動環境では、Sling モデルの使用をお勧めします。

まず、use クラスを持たない info, と呼ばれる 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 を使用して、現在のリソースの title および description にアクセスし、それらを表示します。出力されるファイル /content/my-example.html は次のとおりです。

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

use クラスの追加 adding-a-use-class

現状の info コンポーネントは、その単純な機能を実行するために use クラスを必要としません。ただし、場合によっては、HTL ではできないことを実行する必要があるので、use クラスは必要です。ただし、以下のことに留意してください。

NOTE
use クラスは、HTL だけでは実行できない場合にのみ使用してください。

例えば、info コンポーネントで、リソースの titledescription プロパティを、すべて小文字で表示するとします。HTL には文字列を小文字にするメソッドがないので、次のように Java use-class を追加して /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 の Java ドキュメントを参照してください。

次に、コードの様々な部分を見てみましょう。

ローカルとバンドルの Java クラス local-vs-bundle-java-class

Java use クラスは 2 つの方法でインストールできます。

  • ローカル - ローカルインストールでは、Java ソースファイルは HTL ファイルと並んで、同じリポジトリーフォルダーに配置されます。ソースは、オンデマンドで自動でコンパイルされます。コンパイルやパッケージを別途行う必要はありません。
  • バンドル - バンドルインストールでは、Java クラスは標準の AEM バンドルデプロイメントメカニズムを使用してコンパイルし、OSGi バンドル内にデプロイする必要があります(バンドルされた Java クラスの節を参照)。

どの方法をいつ使用するかを把握するには、次の 2 つの点に注意してください。

  • ローカル Java use クラス ​は、use クラスが対象コンポーネントに特有の場合にお勧めします。
  • バンドル Java use クラス ​は、複数の HTL コンポーネントからアクセスがあるサービスを Java コードで実装する場合にお勧めします。

この例ではローカルインストールを使用します。

Java パッケージはリポジトリーパス java-package-is-repository-path

ローカルインストールを使用するとき、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 {

   ...

}
NOTE
AEM の開発では、リポジトリ項目の名前にハイフンを使用することが推奨されています。ただし、ハイフンは Java パッケージ名では不正です。この理由から、リポジトリパス内のハイフンはすべて、パッケージ名ではアンダースコアに変換する必要があります

WCMUsePojo の拡張 extending-wcmusepojo

Java クラスを HTL に組み込むには多数の方法がありますが、最も簡単な方法は 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

    ...
}

クラスの初期化 initializing-the-class

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();
    }

...

}

コンテキスト context

アクティベートメソッドの通常の用途は、現在のコンテキスト(現在の要求やリソースなど)に基づいて HTL コードに必要な値を事前に計算し、(メンバー変数に)格納することです。

WCMUsePojo クラスを使用すると、HTL ファイル内で使用可能なものと同じコンテキストオブジェクトにアクセスできます(ドキュメントグローバルオブジェクトを参照)。

WCMUsePojo を拡張するクラスでは、以下の名前を使用してコンテキストオブジェクトにアクセスできます。

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

また、この表に示す適切で便利なメソッドを使用して、よく使用されるコンテキストオブジェクトに直接アクセスできます。

ゲッターメソッド getter-methods

use クラスが初期化されると、HTL ファイルが実行されます。この段階で、HTL は通常、use クラスの様々なメンバー変数の状態を引き入れて、プレゼンテーション用にレンダリングします。

HTL ファイル内からこれらの値へアクセスできるようにするには、以下の命名規則に従って、use クラスでカスタムのゲッターメソッドを定義する必要があります。

  • getXyz という形式のメソッドを使用すると、HTL ファイル内で xyz という名前のオブジェクトプロパティがアクセス可能になります。

次のサンプルファイル /apps/my-example/component/info/Info.java では、メソッド getTitle および getDescription により、オブジェクトプロパティ title および description が HTL ファイルのコンテキスト内でアクセス可能になります。

...

public class Info extends WCMUsePojo {

    ...

    public String getLowerCaseTitle() {
        return lowerCaseTitle;
    }

    public String getLowerCaseDescription() {
        return lowerCaseDescription;
    }
}

data-sly-use 属性 data-sly-use-attribute

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>

ローカル識別子 local-identifier

識別子 infodata-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>

プロパティの取得 getting-properties

識別子 info はその後、ゲッターメソッド title および description によってアクセス可能になったオブジェクトプロパティ Info.getTitle および Info.getDescription へのアクセスに使用されます。

この /apps/my-example/component/info/info.html の例での使い方に注意してください。

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

出力 output

これで、/content/my-example.html にアクセスすると、次の /content/my-example.html ファイルが返されます。

<div>
    <h1>my example</h1>
    <p>this is some example content.</p>
</div>
NOTE
この例は、その使用方法を説明するために簡略化しています。実稼動環境では、Sling モデルの使用をお勧めします。

応用 beyond-the-basics

この節では、上記の例よりも高度な追加機能をいくつか紹介します。

  • use クラスにパラメーターを渡す
  • バンドルされた Java use クラス

パラメーターを渡す passing-parameters

初期化時に、use クラスにパラメーターを渡すことができます。

詳しくは、Sling HTL スクリプティングエンジンのドキュメントを参照してください。

バンドルされた Java クラス bundled-java-class

バンドル use クラスの場合、クラスは、AEM で標準の OSGi バンドルデプロイメントメカニズムを使用してコンパイル、パッケージおよびデプロイされる必要があります。ローカルインストールとは異なり、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>
recommendation-more-help
86859df1-0285-4512-b293-0ef9cbea5ee8