Show Menu
トピック×

AEM Screens 用カスタムコンポーネントの開発

以下のチュートリアルでは、AEM Screens 用のカスタムコンポーネントを作成する手順について説明します。AEM Screens では、他の AEM 製品の様々な既存のデザインパターンやテクノロジーを再利用しています。このチュートリアルでは、AEM Screens 用に開発する際の相違点と特別な考慮事項について重点的に説明します。

概要

このチュートリアルは、AEM Screens を初めて使用する開発者を対象としています。このチュートリアルでは、AEM Screens のシーケンスチャネル用に、シンプルな「Hello World」コンポーネントを構築します。作成者は、表示されるテキストをダイアログで更新できます。

前提条件

このチュートリアルを完了するには、以下が必要です。
  1. AEM 6.5 または AEM 6.3 + 最新の Screens 機能パック
  2. ローカル開発環境
チュートリアルの手順とスクリーンショットは、 CRXDE-Lite を使用して実行します。IDE を使用してチュートリアルを完了することもできます。AEM での開発に IDE を使用する方法について詳しくは、 こちら を参照してください。

プロジェクトのセットアップ

Screens プロジェクトのソースコードは、通常、マルチモジュールの Maven プロジェクトとして管理されます。このチュートリアルを効率よく進めるために、 AEM プロジェクトアーキタイプ 13 を使用してプロジェクトを事前に生成してあります。Maven AEM プロジェクトアーキタイプを使用したプロジェクトの作成について詳しくは、 こちら を参照してください。
  1. CRX パッケージマネージャー を使用して、次のパッケージをダウンロードしてインストールします。
    ファイルを入手 (オプション) Eclipse などの IDE を使用して作業する場合は、以下のソースパッケージをダウンロードします。次の Maven コマンドを使用して、プロジェクトをローカルの AEM インスタンスにデプロイします。
    mvn -PautoInstallPackage clean install
    Start HelloWorld SRC Screens We.Retail Run Project
  2. CRX パッケージマネージャー で、次の 2 つのパッケージがインストールされていることを確認します。
    1. screens-weretail-run.ui.content-0.0.1-SNAPSHOT.zip
    2. screens-weretail-run.ui.apps-0.0.1-SNAPSHOT.zip
    CRX パッケージマネージャーを使用してインストールされた Screens We.Retail Run Ui.Content および Ui.Apps パッケージ
  3. screens-weretail-run.ui.apps パッケージでは、 /apps/weretail-run の下にコードがインストールされます。
    このパッケージには、プロジェクトのカスタムコンポーネントをレンダリングするコードが含まれています。このパッケージには、コンポーネントコードのほか、必要な JavaScript または CSS が含まれています。このパッケージには、 screens-weretail-run.core-0.0.1-SNAPSHOT.jar も埋め込まれており、この中に、プロジェクトで必要な Java コードが含まれています。
    このチュートリアルでは、Java コードは記述されません。より複雑なビジネスロジックが必要な場合は、コア Java バンドルを使用してバックエンド Java コードを作成しデプロイできます。
    CRXDE Lite での ui.apps コードの表現
    helloworld コンポーネントは、現時点では、プレースホルダーにすぎません。チュートリアルの過程で機能が追加されて、コンポーネントに表示されるメッセージを作成者が更新できるようになります。
  4. screens-weretail-run.ui.content パッケージでは、以下のパスにコードがインストールされます。
    • /conf/we-retail-run
    • /content/dam/we-retail-run
    • /content/screens/we-retail-run このパッケージには、プロジェクトに必要な初期コンテンツおよび設定構造が含まれています。 /conf/we-retail-run には、We.Retail Run プロジェクトのすべての設定が含まれています。 /content/dam/we-retail-run には、プロジェクトの初期デジタルアセットが含まれています。 /content/screens/we-retail-run には、Screens のコンテンツ構造が含まれています。これらすべてのパスの下に含まれるコンテンツは主に AEM で更新されます。環境(ローカル、開発、ステージング、実稼動)間の一貫性を高めるために、多くの場合、ベースコンテンツ構造がソース管理下に保存されます。
  5. AEM Screens/We.Retail Run プロジェクト ​に移動します。
    AEM のスタートメニューで Screens アイコンをクリックします。We.Retail Run プロジェクトが表示されることを確認します。

Hello World コンポーネントの作成

Hello World コンポーネントは、スクリーンに表示されるメッセージをユーザーが入力できるシンプルなコンポーネントです。このコンポーネントは、 AEM Screens コンポーネントテンプレート:https://github.com/Adobe-Marketing-Cloud/aem-screens-component-template をベースにしています。
AEM Screens には、従来の WCM サイトコンポーネントには必ずしも当てはまらない興味深い制約がいくつかあります。
  • ほとんどの Screens コンポーネントは、ターゲットのデジタルサイネージデバイス上でフルスクリーンで動作する必要があります
  • スライドショーを生成するには、ほとんどの Screens コンポーネントをシーケンスチャネルに埋め込める必要があります
  • オーサリングでは、シーケンスチャネル内の個々のコンポーネントを編集できる必要があります。そのため、フルスクリーンでのレンダリングは問題になりません
  1. CRXDE Lite http://localhost:4502/crx/de/index.jsp (または任意の IDE)で、 /apps/weretail-run/components/content/helloworld. に移動します。
    helloworld コンポーネントに次のプロパティを追加します。
        jcr:title="Hello World"
        sling:resourceSuperType="foundation/components/parbase"
        componentGroup="We.Retail Run - Content"
    
    
    /apps/weretail-run/components/content/helloworld のプロパティ
    helloworld コンポーネントは foundation/components/parbase コンポーネントを拡張したものなので、シーケンスチャネル内で適切に使用できます。
  2. /apps/weretail-run/components/content/helloworld の下に helloworld.html. という名前のファイルを作成します。
    ファイルに以下のように入力します。
    <!--/*
    
     /apps/weretail-run/components/content/helloworld/helloworld.html
    
    */-->
    
    <!--/* production: preview authoring mode + unspecified mode (i.e. on publish) */-->
    <sly data-sly-test.production="${wcmmode.preview || wcmmode.disabled}" data-sly-include="production.html" />
    
    <!--/* edit: any other authoring mode, i.e. edit, design, scaffolding, etc. */-->
    <sly data-sly-test="${!production}" data-sly-include="edit.html" />
    
    
    Screens コンポーネントでは、使用する オーサリングモード に応じて、2 種類のレンダリングが必要になります。
    1. 実稼働 :プレビューまたはパブリッシュモード(wcmmode=disabled)
    2. 編集 :編集、デザイン、基礎、開発者など、他のすべてのオーサリングモードに使用されます。 helloworld.html はスイッチとして機能し、現在アクティブなオーサリングモードを確認し、別の HTL スクリプトにリダイレクトします。編集モード用に edit.html スクリプトを用意し、実稼働モード用に production.html スクリプトを用意するというのが、Screens コンポーネントで一般に使用される規則です。
  3. /apps/weretail-run/components/content/helloworld の下に production.html. という名前のファイルを作成します。
    ファイルに以下のように入力します。
    <!--/*
     /apps/weretail-run/components/content/helloworld/production.html
    
    */-->
    
    <div data-duration="${properties.duration}" class="cmp-hello-world">
     <h1 class="cmp-hello-world__message">${properties.message}</h1>
    </div>
    
    
    上記は、Hello World コンポーネントの実稼働用マークアップです。このコンポーネントはシーケンスチャネルで使用されるので、 data-duration 属性が含まれています。 data-duration 属性は、シーケンスチャネルでシーケンス項目の表示時間を把握するために使用されます。
    このコンポーネントでは、 div タグと h1 タグ(テキストを含む)をレンダリングします。 ${properties.message} は HTL スクリプトの一部で、 message という名前の JCR プロパティのコンテンツを出力します。 message プロパティテキストの値をユーザーが入力できるダイアログを後で作成します。
    また、コンポーネントでは BEM(ブロック要素修飾子)表記が使用されることにも注意してください。BEM は、再利用可能なコンポーネントを容易に作成できる CSS コーディング規則です。BEM は、 AEM のコアコンポーネント で使用される表記です。詳しくは、 https://getbem.com/ を参照してください。
  4. /apps/weretail-run/components/content/helloworld の下に edit.html. という名前のファイルを作成します。
    ファイルに以下のように入力します。
    <!--/*
    
     /apps/weretail-run/components/content/helloworld/edit.html
    
    */-->
    
    <!--/* if message populated */-->
    <div
     data-sly-test.message="${properties.message}"
     class="aem-Screens-editWrapper cmp-hello-world">
     <p class="cmp-hello-world__message">${message}</p>
    </div>
    
    <!--/* empty place holder */-->
    <div data-sly-test="${!message}"
         class="aem-Screens-editWrapper cq-placeholder cmp-hello-world"
         data-emptytext="${'Hello World' @ i18n, locale=request.locale}">
    </div>
    
    
    上記は、Hello World コンポーネントの編集用マークアップです。ダイアログメッセージが既に入力されている場合、最初のブロックにはコンポーネントの編集バージョンが表示されます。
    ダイアログメッセージがまだ入力されていない場合は、2 番目のブロックがレンダリングされます。その場合、 cq-placeholder data-emptytext は、「 Hello World 」というラベルをプレースホルダーとしてレンダリングします。複数のロケールでのオーサリングをサポートするために、ラベルの文字列を i18n を使用して国際化することができます。
  5. Hello World コンポーネントに使用する Screens 画像ダイアログをコピーします。
    既存のダイアログを出発点にして、それに変更を加えるのが最も簡単です。
    1. ダイアログのコピー元: /libs/screens/core/components/content/image/cq:dialog
    2. ダイアログの貼り付け先のパス: /apps/weretail-run/components/content/helloworld
  6. メッセージのタブが含まれるように Hello World ダイアログを更新します。
    次の条件に合致するようにダイアログを更新します。最終的なダイアログの JCR ノード構造は、次のような XML コードになります。
    <?xml version="1.0" encoding="UTF-8"?>
    <jcr:root xmlns:sling="https://sling.apache.org/jcr/sling/1.0" xmlns:cq="https://www.day.com/jcr/cq/1.0" xmlns:jcr="https://www.jcp.org/jcr/1.0" xmlns:nt="https://www.jcp.org/jcr/nt/1.0"
        jcr:primaryType="nt:unstructured"
        jcr:title="Hello World"
        sling:resourceType="cq/gui/components/authoring/dialog">
        <content
            jcr:primaryType="nt:unstructured"
            sling:resourceType="granite/ui/components/coral/foundation/tabs"
            size="L">
            <items jcr:primaryType="nt:unstructured">
                <message
                    jcr:primaryType="nt:unstructured"
                    jcr:title="Message"
                    sling:resourceType="granite/ui/components/coral/foundation/fixedcolumns">
                    <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="Message for component to display"
                                    fieldLabel="Message"
                                    name="./message"/>
                            </items>
                        </column>
                    </items>
                </message>
                <sequence
                    jcr:primaryType="nt:unstructured"
                    jcr:title="Sequence"
                    sling:resourceType="granite/ui/components/coral/foundation/fixedcolumns">
                    <items jcr:primaryType="nt:unstructured">
                        <column
                            jcr:primaryType="nt:unstructured"
                            sling:resourceType="granite/ui/components/coral/foundation/container">
                            <items jcr:primaryType="nt:unstructured">
                                <duration
                                    jcr:primaryType="nt:unstructured"
                                    sling:resourceType="granite/ui/components/coral/foundation/form/numberfield"
                                    defaultValue=""
                                    fieldDescription="Amount of time the image will be shown in the sequence, in milliseconds"
                                    fieldLabel="Duration (ms)"
                                    min="0"
                                    name="./duration"/>
                            </items>
                        </column>
                    </items>
                </sequence>
            </items>
        </content>
    </jcr:root>
    
    
    メッセージのテキストフィールドは message というプロパティに保存され、期間の数値フィールドは duration というプロパティに保存されます。 /apps/weretail-run/components/content/helloworld/production.html では、これら 2 つのプロパティは ${properties.message} および ${properties.duration} として HTL で参照されます。
    Hello World - 完成したダイアログ

クライアント側ライブラリの作成

クライアント側ライブラリは、AEM の実装で必要な CSS および JavaScript ファイルの編成および管理のための仕組みを提供します。
AEM Screens コンポーネントは、編集モードとプレビュー/実稼働モードではレンダリングが異なります。2 つのクライアントライブラリが作成されます。1 つは編集モード用、もう 1 つはプレビュー/実稼働用です。
  1. Hello World コンポーネントのクライアント側ライブラリ用のフォルダーを作成します。
    /apps/weretail-run/components/content/helloworld の下に、 clientlibs という名前の新しいフォルダーを作成します。
  2. clientlibs フォルダーの下に、名前が shared cq:ClientLibraryFolder. 型の新しいノードを作成します。
  3. 共有クライアントライブラリに次のプロパティを追加します。
    • allowProxy | Boolean | true
    • categories | String # | cq.screens.components
    /apps/weretail-run/components/content/helloworld/clientlibs/shared のプロパティ
    categories プロパティは、クライアントライブラリを識別する文字列です。cq.screens.componentscategory は、編集モードとプレビュー/実稼働モードの両方で使用されます。したがって、sharedclientlib に定義された CSS/JS は、すべてのモードに読み込まれます。
    実稼働環境では、直接 /apps にパスを公開しないことをお勧めします。allowProxy プロパティにより、クライアントライブラリの CSS と JS が /etc.clientlibs というプレフィックスを付けて参照されるようになります。
  4. 共有フォルダーの下に css.txt という名前のファイルを作成します。
    ファイルに以下のように入力します。
    #base=css
    
    styles.less
    
    
  5. shared フォルダーの下に css という名前のフォルダーを作成します。 css フォルダーの下に、 style.less という名前のファイルを追加します。クライアントライブラリの構造は次のようになります。
    このチュートリアルでは、CSS を直接記述するのではなく、LESS を使用します。 LESS は、CSS 変数、ミックスイン、関数をサポートしている一般的な CSS プリコンパイラーです。AEM のクライアントライブラリは、LESS によるコンパイルをネイティブにサポートしています。Sass などのプリコンパイラーも使用できますが、その場合は、AEM の外部でコンパイルする必要があります。
  6. /apps/weretail-run/components/content/helloworld/clientlibs/shared/css/styles.less に以下を入力します。
    /**
        Shared Styles
       /apps/weretail-run/components/content/helloworld/clientlibs/shared/css/styles.less
    
    **/
    
    .cmp-hello-world {
        background-color: #fff;
    
     &__message {
      color: #000;
      font-family: Helvetica;
      text-align:center;
     }
    }
    
    
  7. クライアントライブラリフォルダー shared をコピーして貼り付けて、 production という名前の新しいクライアントライブラリを作成します。
    共有クライアントライブラリをコピーして実稼働用の新しいクライアントライブラリを作成する
  8. 実稼働用クライアントライブラリの categories プロパティを cq.screens.components.production. に更新します。
    これにより、プレビュー/実稼働モードの場合のみ、スタイルが読み込まれるようになります。
    /apps/weretail-run/components/content/helloworld/clientlibs/production のプロパティ
  9. /apps/weretail-run/components/content/helloworld/clientlibs/production/css/styles.less に以下を入力します。
    /**
        Production Styles
       /apps/weretail-run/components/content/helloworld/clientlibs/production/css/styles.less
    
    **/
    .cmp-hello-world {
    
        height: 100%;
        width: 100%;
        position: fixed;
    
     &__message {
    
      position: relative;
      font-size: 5rem;
      top:25%;
     }
    }
    
    
    上記のスタイルでは、実稼働モードの場合のみ、スクリーンの中央にメッセージが表示されます。
3 番目のクライアントライブラリカテゴリ cq.screens.components.edit は、コンポーネントに編集専用のスタイルを追加する場合に使用できます。
クライアントライブラリカテゴリ
使用方法
cq.screens.components
スタイルとスクリプトが編集モードと実稼働モードの両方で共有される
cq.screens.components.edit
スタイルとスクリプトが編集モードでのみ使用される
cq.screens.components.production
スタイルとスクリプトが実稼働モードでのみ使用される

デザインページの作成

AEM Screens では、 静的ページテンプレート デザイン設定 を使用して、グローバルな変更に対応します。デザイン設定は、チャネル上で使用できる ParSys コンポーネントを設定する場合によく使用されます。これらの設定をアプリに固有の方法で保存することをお勧めします。
We.Retail Run プロジェクトに固有のすべての設定を保存する We.Retail Run Design ページを以下の手順で作成します。
  1. CRXDE Lite http://localhost:4502/crx/de/index.jsp#/apps/settings/wcm/designs )で /apps/settings/wcm/designs に移動します。
  2. designs フォルダーの下に cq:Page 型の we-retail-run という名前の新しいノードを作成します。
  3. we-retail-run ページの下に、 nt:unstructured 型の jcr:content という名前の別のノードを追加します。この jcr:content ノードに次のプロパティを追加します。
    名前
    タイプ
    jcr:title
    文字列
    We.Retail Run
    sling:resourceType
    文字列
    wcm/core/components/designer
    cq:doctype
    文字列
    html_5
    /apps/settings/wcm/designs/we-retail-run のデザインページ

シーケンスチャネルの作成

Hello World コンポーネントは、シーケンスチャネルで使用するためのものです。このコンポーネントをテストするために、新しいシーケンスチャネルを作成します。
  1. AEM のスタートメニューで、 Screens We.Retail Run に移動し、「 チャネル 」を選択します。
  2. 作成 」ボタンをクリックします。
    1. エンティティを作成 」を選択します。
  3. 作成ウィザードで、以下の操作をおこないます。
  4. テンプレートの手順 - 「 シーケンスチャネル 」を選択します
    1. プロパティの手順
    • 「基本」タブ/「タイトル」に「 Idle Channel 」を入力
    • 「チャネル」タブ/「 チャンネルをオンラインにする 」をオン
  5. Idle Channel のページプロパティを開きます。前のセクションで作成したデザインページ /apps/settings/wcm/designs/we-retail-run, を指すように、「デザイン」フィールドを更新します。
    /apps/settings/wcm/designs/we-retail-run を指しているデザイン設定
  6. 新しく作成した Idle Channel を開いて編集します。
  7. ページモードを​ デザイン ​モードに切り替えます。
    1. ParSys の​ レンチ ​アイコンをクリックして、使用できるコンポーネントを設定します。
    2. Screens 」グループと「 We.Retail Run - Content 」グループを選択します。
  8. ページモードを​ 編集 ​に切り替えます。これで、Hello World コンポーネントをページに追加し、他のシーケンスチャネルコンポーネントと組み合わせることができるようになりました。
  9. CRXDE Lite http://localhost:4502/crx/de/index.jsp#/apps/settings/wcm/designs/we-retail-run/jcr%3Acontent/sequencechannel/par )で /apps/settings/wcm/designs/we-retail-run/jcr:content/sequencechannel/par に移動します。 components プロパティに group:Screens group:We.Retail Run - Content が含まれていることがわかります。
    /apps/settings/wcm/designs/we-retail-run の下のデザイン設定

カスタムハンドラーのテンプレート

カスタムコンポーネントがアセット(画像、ビデオ、フォント、アイコンなど)、特定のアセットレンディションまたはクライアント側ライブラリ(css、js など)などの外部リソースを使用している場合、デフォルトでは HTML マークアップのみがバンドルされるので、オフライン設定には自動的に追加されません。
プレーヤーにダウンロードされる正確なアセットをカスタマイズして最適化するには、カスタムコンポーネントの拡張メカニズムを使用して、Screens のオフラインキャッシュロジックに依存関係を公開します。
次の節では、カスタムオフラインリソースハンドラーのテンプレートと、そのプロジェクトに対する pom.xml の最小要件について説明します。
package …;

import javax.annotation.Nonnull;

import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.Service;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceUtil;
import org.apache.sling.api.resource.ValueMap;

import com.adobe.cq.screens.visitor.OfflineResourceHandler;

@Service(value = OfflineResourceHandler.class)
@Component(immediate = true)
public class MyCustomHandler extends AbstractResourceHandler {

 @Reference
 private …; // OSGi services injection

 /**
  * The resource types that are handled by the handler.
  * @return the handled resource types
  */
 @Nonnull
 @Override
 public String[] getSupportedResourceTypes() {
     return new String[] { … };
 }

 /**
  * Accept the provided resource, visit and traverse it as needed.
  * @param resource The resource to accept
  */
 @Override
 public void accept(@Nonnull Resource resource) {
     ValueMap properties = ResourceUtil.getValueMap(resource);
     
     /* You can directly add explicit paths for offline caching using the `visit`
        method of the visitor. */
     
     // retrieve a custom property from the component
     String myCustomRenditionUrl = properties.get("myCustomRenditionUrl", String.class);
     // adding that exact asset/rendition/path to the offline manifest
     this.visitor.visit(myCustomRenditionUrl);
     
     
     /* You can delegate handling for dependent resources so they are also added to
        the offline cache using the `accept` method of the visitor. */
     
     // retrieve a referenced dependent resource
     String referencedResourcePath = properties.get("myOtherResource", String.class);
     ResourceResolver resolver = resource.getResourceResolver();
     Resource referencedResource = resolver.getResource(referencedResourcePath);
     // let the handler for that resource handle it
     if (referencedResource != null) {
         this.visitor.accept(referencedResource);
     }
   }
}

次のコードは、そのプロジェクトに対する pom.xml の最小要件を示しています。
   <dependencies>
        …
        <!-- Felix annotations -->
        <dependency>
            <groupId>org.apache.felix</groupId>
            <artifactId>org.apache.felix.scr.annotations</artifactId>
            <version>1.9.0</version>
            <scope>provided</scope>
        </dependency>

        <!-- Screens core bundle with OfflineResourceHandler/AbstractResourceHandler -->
        <dependency>
            <groupId>com.adobe.cq.screens</groupId>
            <artifactId>com.adobe.cq.screens</artifactId>
            <version>1.5.90</version>
            <scope>provided</scope>
        </dependency>
        …
      </dependencies>

まとめ

以下のビデオでは、完成したコンポーネントと、それをシーケンスチャネルに追加する方法を示しています。この後、チャネルはロケーションのディスプレイに追加され、最終的に Screens プレーヤーに割り当てられます。

完成したコード

チュートリアルで完成したコードは以下のとおりです。 screens-weretail-run.ui.apps-0.0.1-SNAPSHOT.zip screens-weretail-run.ui.content-0.0.1-SNAPSHOT.zip は、コンパイル済みの AEM パッケージです。SRC-screens-wertail-run-0.0.1.zip は、Maven を使用してデプロイできる未コンパイルのソースコードです。