AEM開発者ブログ by YAMATO

アドビ社のデリバリーパートナー大和株式会社のAEM開発者ブログです。

HTL to Java, Java to HTL

AEM Developerの皆様お疲れさまです。大和株式会社の狩野です。

Qiitaのアドベントカレンダーに便乗して始めた記事投稿イベント6日目です。 今日6日目の内容は、HTL to Java, Java to HTLです。

5日目の記事→【AEM as a Cloud】ページプロパティのバルク編集

今回はHTLで定義した値をJava側に渡す方法と、その逆のJavaで定義した値をHTLに渡す方法について書きます。 HTL→JavaとJava→HTLなので、「HTL to Java, Java to HTL」というタイトルなわけですね。

HTL to Java

HTLで定義した値をJava側で使う方法についてです。
この例では、HTLで定義したhtlValueという変数に格納した値をJavaで取り出します。

HTL側の記述

<sly data-sly-use.comp="${ 'path.to.TutorialComponent' @ htlValue='testString' }"></sly>

Java側の記述

Java側の記述は、WCMUsePojo継承クラスとSling Modelsの2つがあります。
現在の主流はSling Modelsではありますが、一応WCMUsePojo継承クラスでの記法も書いておきます。

WCMUsePojo継承クラス

com.adobe.cq.sightly.WCMUsePojo

import com.adobe.cq.sightly.WCMUsePojo;

public class TutorialComponent extends WCMUsePojo {
    @Override
    public void activate() {
        String htlValue = get("htlValue", String.class);
    }
}

WCMUsePojoクラスが持ってる get メソッドで取得できます。

Sling Models

Sling Models

import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.models.annotations.Model;
import org.apache.sling.models.annotations.DefaultInjectionStrategy;
import org.apache.sling.models.annotations.injectorspecific.RequestAttribute;

@Model(
    adaptables = {SlingHttpServletRequest.class},
    defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL
)
public class TutorialComponent {
    @RequestAttribute
    private String htlValue;
}

行数が多くてごちゃごちゃして見えますが、 @RequestAttribute アノテーションを付与して宣言するだけで値を取得できてます。

Java to HTL

Javaで定義した値をHTLに出力する方法です。

この例では、javaの getTestString() メソッドで return されている 「java側で定義した値」という文字列がHTL上に出力されます。
WKND Tutorial - Custom Component では、JavaクラスのフィールドにHTLに出力する変数を定義していますが、定義する必要はありません(Javaにおいて通常フィールドはprivateで定義しますが、privateだとそもそもHTL側からアクセスすることが出来ない

Java側の記述

import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.models.annotations.Model;
import org.apache.sling.models.annotations.DefaultInjectionStrategy;

@Model(
    adaptables = {SlingHttpServletRequest.class},
    defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL
)
public class TutorialComponent {
    public String getTestString() {
        return "java側で定義した値";
    }
}

HTL側の記述

<sly data-sly-use.tutorial="ltd.co.yamato.TutorialComponent"></sly>
<div data-sly-text="${ tutorial.testString }"></div>

応用

少しハック的なやり方ですが、 get + 名前 でメソッドを宣言している場合、HTL側でその「名前」だけを宣言すればメソッドを呼び出せます。
これを利用して、以下のように頭に get がついているAEM標準APIが搭載しているメソッドをHTLで呼び出すことも可能です。

${ currentPage.path }

currentPage はHTL内で自動で宣言されているオブジェクトなので自分で定義する必要はありません。
それ以外にHTLで宣言されているオブジェクトはHTL Global Objectに一覧があります。

最後に

以上となります。明日は青葉さんが執筆してくれます。内容は「静的テンプレートと編集可能テンプレートの共存」です。お楽しみに。僕も楽しみにしてます。