SPAコンポーネントのAEMコンポーネントへのマッピング

AEM SPA Editor JS SDKを使用して、AngularコンポーネントをAdobe Experience Manager(AEM)コンポーネントにマッピングする方法について説明します。 コンポーネントマッピングを使用すると、AEM SPA Editor内で、従来のAEMオーサリングと同様に、SPAコンポーネントを動的に更新できます。

この章では、AEM JSONモデルAPIについて詳しく説明し、AEMコンポーネントによって公開されたJSONコンテンツをpropとしてAngularコンポーネントに自動的に挿入する方法について説明します。

目的

  1. AEMコンポーネントをSPAコンポーネントにマッピングする方法について説明します。
  2. コンテナ​コンポーネントと​コンテンツ​コンポーネントの違いを理解します。
  3. 既存のAngularコンポーネントにマッピングする新しいAEMコンポーネントを作成します。

作成する内容

この章では、指定されたText SPAコンポーネントがAEM Textコンポーネントにどのようにマッピングされているかを調べます。 新しいImage SPAコンポーネントが作成され、SPAで使用してAEMでオーサリングできます。 レイアウトコンテナ​および​テンプレートエディター​ポリシーの初期設定済み機能も使用して、外観が少し変化するビューを作成します。

チャプターサンプルの最終オーサリング

前提条件

ローカル開発環境の設定に必要なツールと手順を確認します。

コードの取得

  1. このチュートリアルの開始点をGitからダウンロードします。

    $ git clone git@github.com:adobe/aem-guides-wknd-spa.git
    $ cd aem-guides-wknd-spa
    $ git checkout Angular/map-components-start
    
  2. Mavenを使用して、コードベースをローカルのAEMインスタンスにデプロイします。

    $ mvn clean install -PautoInstallSinglePackage
    

    AEM 6.xを使用する場合は、classicプロファイルを追加します。

    $ mvn clean install -PautoInstallSinglePackage -Pclassic
    

GitHubで完成したコードをいつでも表示したり、ブランチAngular/map-components-solutionに切り替えてコードをローカルでチェックアウトしたりできます。

マッピング方法

基本的な概念は、SPAコンポーネントをAEMコンポーネントにマッピングすることです。 AEMコンポーネントを使用して、サーバー側で実行し、JSONモデルAPIの一部としてコンテンツを書き出す。 JSONコンテンツは、ブラウザーでクライアント側を実行するSPAで使用されます。 SPAコンポーネントとAEMコンポーネントの間に1対1のマッピングが作成されます。

AEMコンポーネントとAngularコンポーネントのマッピングの概要

AEMコンポーネントとAngularコンポーネントのマッピングの概要

Inspect the Text Component

AEMプロジェクトアーキタイプは、AEM テキストコンポーネントにマッピングされるTextコンポーネントを提供します。 これは、AEMから​content​をレンダリングする​content​コンポーネントの例です。

コンポーネントの動作を見てみましょう。

JSONモデルのInspect

  1. SPAのコードを調べる前に、AEMが提供するJSONモデルを理解しておくことが重要です。 コアコンポーネントライブラリに移動し、テキストコンポーネントのページを表示します。 コアコンポーネントライブラリは、すべてのAEMコアコンポーネントの例を提供しています。

  2. 次のいずれかの例の「JSON」タブを選択します。

    テキストJSONモデル

    次の3つのプロパティが表示されます。textrichText、および:type

    :type は、AEMコンポーネントの(また sling:resourceType はパス)をリストする予約済みプロパティです。:typeの値は、AEMコンポーネントをSPAコンポーネントにマッピングするために使用されます。

    textrichText は、SPAコンポーネントに公開される追加のプロパティです。

Inspect the Textコンポーネント

  1. 新しいターミナルを開き、プロジェクト内のui.frontendフォルダーに移動します。 npm installを実行し、npm startを実行して​webpack開発サーバー​を起動します。

    $ cd ui.frontend
    $ npm run start:mock
    

    ui.frontendモジュールは、現在、モックJSONモデルを使用するように設定されています。

  2. 新しいブラウザウィンドウが開いてhttp://localhost:4200/content/wknd-spa-angular/us/en/home.htmlが表示されます。

    モックコンテンツを含むWebpack Devサーバー

  3. 任意のIDEで、WKND SPA用のAEMプロジェクトを開きます。 ui.frontendモジュールを展開し、ui.frontend/src/app/components/text/text.component.tsの下の​text.component.ts​ファイルを開きます。

    Text.jsAngularコンポーネントのソースコード

  4. 最初に検査する領域は、~35行目のclass TextComponentです。

    export class TextComponent {
        @Input() richText: boolean;
        @Input() text: string;
        @Input() itemName: string;
    
        @HostBinding('innerHtml') get content() {
            return this.richText
            ? this.sanitizer.bypassSecurityTrustHtml(this.text)
            : this.text;
        }
        @HostBinding('attr.data-rte-editelement') editAttribute = true;
    
        constructor(private sanitizer: DomSanitizer) {}
    }
    

    @Input() decoratorは、マッピングされたJSONオブジェクトを介して値が設定されるフィールドを宣言するために使用されます。

    @HostBinding('innerHtml') get content() は、の値からオーサリング済みテキストコンテンツを公開するメソッドで this.textす。コンテンツがリッチテキスト(this.richTextフラグで指定)の場合、Angularの組み込みのセキュリティは迂回されます。 AngularのDomSanitizerは、生のHTMLを「スクラブ」し、クロスサイトスクリプティングの脆弱性を防ぐために使用されます。 メソッドは、@HostBindingデコレーターを使用してinnerHtmlプロパティにバインドされます。

  5. 次に、~24行目のTextEditConfigを検査します。

    const TextEditConfig = {
        emptyLabel: 'Text',
        isEmpty: cqModel =>
            !cqModel || !cqModel.text || cqModel.text.trim().length < 1
    };
    

    上記のコードは、AEMオーサー環境でプレースホルダーをレンダリングするタイミングを決定する役割を果たします。 isEmptyメソッドが​true​を返す場合は、プレースホルダーがレンダリングされます。

  6. 最後に、 ~53行目のMapTo呼び出しを見てみましょう。

    MapTo('wknd-spa-angular/components/text')(TextComponent, TextEditConfig );
    

    ​MapToiは、AEM SPA Editor JS SDK(@adobe/cq-angular-editable-components)で提供されます。パスwknd-spa-angular/components/textは、AEMコンポーネントのsling:resourceTypeを表します。 このパスは、前に確認したJSONモデルで公開された:typeと一致します。 ​MapToparses JSONモデルの応答を取得し、正しい値をSPAコンポーネ @Input() ントの変数に渡します。

    AEMのTextコンポーネント定義はui.apps/src/main/content/jcr_root/apps/wknd-spa-angular/components/textにあります。

  7. ui.frontend/src/mocks/json/en.model.jsonにある​en.model.json​ファイルを変更して、実験を行います。

    ~行62で、最初のText値を更新し、H1​タグと​u​タグを使用します。

        "text": {
            "text": "<h1><u>Hello World!</u></h1>",
            "richText": true,
            ":type": "wknd-spa-angular/components/text"
        }
    

    ブラウザーに戻り、webpack開発サーバー​が提供する効果を確認します。

    テキストモデルの更新

    richTextプロパティを​true / false​の間で切り替えて、実行中のレンダリングロジックを確認してください。

  8. Inspect text.component.html (ui.frontend/src/app/components/text/text.component.html)

    コンポーネントの内容全体がinnerHTMLプロパティによって設定されるので、このファイルは空です。

  9. app.module.ts​をui.frontend/src/app/app.module.tsにInspectします。

    @NgModule({
    imports: [
        BrowserModule,
        SpaAngularEditableComponentsModule,
        AppRoutingModule
    ],
    providers: [ModelManagerService, { provide: APP_BASE_HREF, useValue: '/' }],
    declarations: [AppComponent, TextComponent, PageComponent, HeaderComponent],
    entryComponents: [TextComponent, PageComponent],
    bootstrap: [AppComponent]
    })
    export class AppModule {}
    

    TextComponent​は明示的に含まれるのではなく、AEM SPA Editor JS SDKが提供する​AEMResponsiveGridComponent​を介して動的に含まれます。 したがって、app.module.ts' entryComponents配列にリストする必要があります。

画像コンポーネントの作成

次に、AEM AngularコンポーネントにマッピングされるImage画像コンポーネントを作成します。 Imageコンポーネントは、content​コンポーネントの別の例です。

Inspect the JSON

SPAコードを調べる前に、AEMから提供されたJSONモデルを調べます。

  1. コアコンポーネントライブラリの画像の例に移動します。

    画像コアコンポーネントのJSON

    srcaltおよびtitleのプロパティは、SPA Imageコンポーネントの設定に使用されます。

    メモ

    開発者がアダプティブな遅延読み込みコンポーネントを作成できる、その他の画像プロパティ(lazyEnabledwidths)が公開されています。 このチュートリアルで作成されるコンポーネントはシンプルで、これらの高度なプロパティは​使用​しません。

  2. IDEに戻り、ui.frontend/src/mocks/json/en.model.jsonen.model.jsonを開きます。 これはプロジェクトの新しいコンポーネントなので、画像JSONのモックを作成する必要があります。

    ~行70に、imageモデルのJSONエントリを追加し(2番目のtext_386303036の後の末尾のコンマ,を忘れないでください)、:itemsOrder配列を更新します。

    ...
    ":items": {
                ...
                "text_386303036": {
                    "text": "<p>A new text component.</p>\r\n",
                    "richText": true,
                    ":type": "wknd-spa-angular/components/text"
                    },
                "image": {
                    "alt": "Rock Climber in New Zealand",
                    "title": "Rock Climber in New Zealand",
                    "src": "/mocks/images/adobestock-140634652.jpeg",
                    ":type": "wknd-spa-angular/components/image"
                }
            },
            ":itemsOrder": [
                "text",
                "text_386303036",
                "image"
            ],
    

    このプロジェクトには、/mock-content/adobestock-140634652.jpegにサンプルイメージが含まれており、webpack開発サーバー​で使用されます。

    en.model.jsonは、で参照できます。

  3. コンポーネントで表示するストック写真を追加します。

    ui.frontend/src/mocksの下に​images​という名前の新しいフォルダーを作成します。 adobestock-140634652.jpegをダウンロードし、新しく作成した​images​フォルダーに配置します。 必要に応じて、自分の画像を自由に使用できます。

画像コンポーネントの実装

  1. webpack開発サーバー​を起動したら停止します。

  2. ui.frontendフォルダー内からAngularCLIのng generate componentコマンドを実行して、新しい画像コンポーネントを作成します。

    $ ng generate component components/image
    
  3. IDEで、image.component.ts​をui.frontend/src/app/components/image/image.component.tsで開き、次のように更新します。

    import {Component, Input, OnInit} from '@angular/core';
    import {MapTo} from '@adobe/cq-angular-editable-components';
    
    const ImageEditConfig = {
    emptyLabel: 'Image',
    isEmpty: cqModel =>
        !cqModel || !cqModel.src || cqModel.src.trim().length < 1
    };
    
    @Component({
    selector: 'app-image',
    templateUrl: './image.component.html',
    styleUrls: ['./image.component.scss']
    })
    export class ImageComponent implements OnInit {
    
    @Input() src: string;
    @Input() alt: string;
    @Input() title: string;
    
    constructor() { }
    
    get hasImage() {
        return this.src && this.src.trim().length > 0;
    }
    
    ngOnInit() { }
    }
    
    MapTo('wknd-spa-angular/components/image')(ImageComponent, ImageEditConfig);
    

    ImageEditConfig は、プロパティが設定されているかどうかに基づいて、AEMでオーサープレースホルダーをレンダリングするかどうかを src 決定する設定です。

    @Input()srcalt、はJSON APIか title らマッピングされたプロパティです。

    hasImage() は、イメージをレンダリングする必要があるかどうかを指定するメソッドです。

    MapTo は、 SPAコンポーネントを、にあるAEMコンポーネントにマッピングしま ui.apps/src/main/content/jcr_root/apps/wknd-spa-angular/components/imageす。

  4. image.component.html​を開き、次のように更新します。

    <ng-container *ngIf="hasImage">
        <img class="image" [src]="src" [alt]="alt" [title]="title"/>
    </ng-container>
    

    hasImageが​true​を返した場合、<img>要素がレンダリングされます。

  5. image.component.scss​を開き、次のように更新します。

    :host-context {
        display: block;
    }
    
    .image {
        margin: 1rem 0;
        width: 100%;
        border: 0;
    }
    
    メモ

    AEM SPAエディターのプレースホルダーが正しく機能するには、:host-contextルールが​重要​です。 AEMページエディターで作成するSPAコンポーネントには、少なくともこのルールが必要です。

  6. app.module.tsを開き、ImageComponententryComponents配列に追加します。

    entryComponents: [TextComponent, PageComponent, ImageComponent],
    

    TextComponentと同様に、ImageComponentは動的に読み込まれ、entryComponents配列に含める必要があります。

  7. webpack開発サーバー​を起動して、ImageComponentレンダーを確認します。

    $ npm run start:mock
    

    モックに追加された画像

    SPAに追加された画像

    メモ

    ボーナスチャレンジ:画像の下にの値をキャプションとして表 title 示する新しいメソッドを実装します。

AEMのポリシーの更新

ImageComponentコンポーネントは、webpack開発サーバー​にのみ表示されます。 次に、更新されたSPAをAEMにデプロイし、テンプレートポリシーを更新します。

  1. webpack開発サーバー​を停止し、プロジェクトの​root​から、Mavenのスキルを使用してAEMに変更をデプロイします。

    $ cd aem-guides-wknd-spa
    $ mvn clean install -PautoInstallSinglePackage
    
  2. AEMの開始画面から、ツール > テンプレート > WKND SPAAngular​に移動します。

    SPA Page​を選択して編集します。

    ページテンプレートをSPA

  3. レイアウトコンテナ​を選択し、ポリシー​アイコンをクリックしてポリシーを編集します。

    レイアウトコンテナポリシー

  4. 許可されているコンポーネント > WKND SPAAngular — コンテンツ >の下で、画像​コンポーネントを確認します。

    画像コンポーネントを選択

    Default Components > Add mapping​を選択し、Image - WKND SPAAngular- Content​コンポーネントを選択します。

    デフォルトコンポーネントの設定

    MIMEタイプ​をimage/*と入力します。

    完了」をクリックして、ポリシーの更新を保存します。

  5. レイアウトコンテナ​で、テキスト​コンポーネントの​ポリシー​アイコンをクリックします。

    テキストコンポーネントポリシーアイコン

    WKND SPA Text​という名前の新しいポリシーを作成します。 「プラグイン / 書式 」で、すべてのボックスをオンにして追加の書式設定オプションを有効にします。

    RTEフォーマットの有効化

    プラグイン > 段落スタイル​で、「段落スタイル​を有効にする」チェックボックスをオンにします。

    段落スタイルを有効にする

    完了」をクリックして、ポリシーの更新を保存します。

  6. ホームページ http://localhost:4502/editor.html/content/wknd-spa-angular/us/en/home.htmlに移動します。

    また、Textコンポーネントを編集し、フルスクリーン​モードで段落スタイルを追加することもできます。

    全画面表示のリッチテキスト編集

  7. また、アセットファインダー​から画像をドラッグ&ドロップすることもできます。

    画像のドラッグ&ドロップ

  8. AEM Assetsを使用して独自の画像を追加するか、標準のWKNDリファレンスサイトの完成したコードベースをインストールします。 WKND参照サイトには、WKND SPAで再利用できる多くの画像が含まれています。 パッケージは、AEM Package Managerを使用してインストールできます。

    パッケージマネージャーによるwknd.allのインストール

Inspect the Layout Container

レイアウトコンテナ​のサポートは、AEM SPA Editor SDKによって自動的に提供されます。 レイアウトコンテナ​は、名前で示されているように、 コンテナ​コンポーネントです。 コンテナコンポーネントは、他の​コンポーネントを表すJSON構造を受け入れ、動的にインスタンス化するコンポーネントです。

ここでは、レイアウトコンテナをさらに詳しく調べます。

  1. IDEで​responsive-grid.component.ts​をui.frontend/src/app/components/responsive-gridで開きます。

    import { AEMResponsiveGridComponent,MapTo } from '@adobe/cq-angular-editable-components';
    
    MapTo('wcm/foundation/components/responsivegrid')(AEMResponsiveGridComponent);
    

    AEMResponsiveGridComponentは、AEM SPA Editor SDKの一部として実装され、import-componentsを介してプロジェクトに含まれます。

  2. ブラウザーで、http://localhost:4502/content/wknd-spa-angular/us/en.model.jsonに移動します。

    JSONモデルAPI — レスポンシブグリッド

    レイアウトコンテナ​コンポーネントはwcm/foundation/components/responsivegridsling:resourceTypeを持ち、TextコンポーネントとImageコンポーネントと同様に、:typeプロパティを使用してSPAエディターで認識されます。

    レイアウトモードを使用してコンポーネントのサイズを変更する場合と同じ機能をSPA Editorで使用できます。

  3. http://localhost:4502/editor.html/content/wknd-spa-angular/us/en/home.htmlに戻ります。 画像​コンポーネントを追加し、レイアウト​オプションを使用してサイズ変更を試みます。

    レイアウトモードを使用した画像のサイズ変更

  4. JSONモデルhttp://localhost:4502/content/wknd-spa-angular/us/en.model.jsonを再度開き、JSONの一部としてcolumnClassNamesを観察します。

    列クラス名

    クラス名aem-GridColumn--default--4は、12列のグリッドに基づいて、幅が4列であるコンポーネントを示します。 レスポンシブグリッドの詳細については、を参照してください。

  5. IDEに戻り、ui.appsモジュール内にui.apps/src/main/content/jcr_root/apps/wknd-spa-angular/clientlibs/clientlib-gridに定義されたクライアント側ライブラリがあります。 less/grid.less ファイルを開きます。

    このファイルは、レイアウトコンテナ​で使用されるブレークポイント(defaulttabletphone)を決定します。 このファイルは、プロジェクト仕様に応じてカスタマイズすることを目的としています。 現在、ブレークポイントは1200px650pxに設定されています。

  6. Textコンポーネントのレスポンシブ機能と更新されたリッチテキストポリシーを使用して、次のようなビューを作成できます。

    チャプターサンプルの最終オーサリング

おめでとうございます。

これで、SPAコンポーネントをAEMコンポーネントにマッピングする方法と、新しいImageコンポーネントを実装する方法を学びました。 また、レイアウトコンテナ​のレスポンシブ機能を調べることもできます。

GitHubで完成したコードをいつでも表示したり、ブランチAngular/map-components-solutionに切り替えてコードをローカルでチェックアウトしたりできます。

次の手順

ナビゲーションとルーティング - SPAエディターSDKを使用してAEMページにマッピングすることで、SPAの複数のビューをサポートする方法を説明します。動的ナビゲーションは、Angularルーターを使用して実装され、既存のヘッダーコンポーネントに追加されます。

ボーナス — ソース管理に対する構成の保持

多くの場合、特にAEMプロジェクトの開始時に、テンプレートや関連するコンテンツポリシーなどの設定をソース管理に保持すると役立ちます。 これにより、すべての開発者が同じコンテンツと設定のセットに対して作業を行い、環境間の一貫性をさらに高めることができます。 プロジェクトがある程度の成熟度に達すると、テンプレート管理の手法を特別なパワーユーザーのグループに引き継ぐことができます。

次の手順は、Visual Studio Code IDEとVSCode AEM Syncを使用して実行しますが、AEMのローカルインスタンスから​pull<a3/または import に設定した任意のツールとIDEを使用して実行できます。

  1. Visual Studio Code IDEで、Marketplace拡張機能を使用して​VSCode AEM Sync​がインストールされていることを確認します。

    VSCode AEM Sync

  2. プロジェクトエクスプローラーで、 ui.content​モジュールを展開し、 /conf/wknd-spa-angular/settings/wcm/templatesに移動します。

  3. フォルダーを右 クリック templates し、「 AEM Serverからインポ ート」を選択します

    VSCodeインポートテンプレート

  4. コンテンツを読み込む手順を繰り返しますが、/conf/wknd-spa-angular/settings/wcm/policiesにある​policies​フォルダーを選択します。

  5. ui.content/src/main/content/META-INF/vault/filter.xmlにあるfilter.xmlファイルをInspectします。

    <!--ui.content filter.xml-->
    <?xml version="1.0" encoding="UTF-8"?>
     <workspaceFilter version="1.0">
         <filter root="/conf/wknd-spa-angular" mode="merge"/>
         <filter root="/content/wknd-spa-angular" mode="merge"/>
         <filter root="/content/dam/wknd-spa-angular" mode="merge"/>
         <filter root="/content/experience-fragments/wknd-spa-angular" mode="merge"/>
     </workspaceFilter>
    

    filter.xmlファイルは、パッケージと共にインストールされるノードのパスを識別します。 各フィルターのmode="merge"は、既存のコンテンツは変更されず、新しいコンテンツのみが追加されることを示しています。 コンテンツ作成者はこれらのパスを更新する可能性があるので、コードデプロイメントではコンテンツを上書き​しない​ことが重要です。 フィルタ要素の使用について詳しくは、FileVaultのドキュメントを参照してください。

    ui.content/src/main/content/META-INF/vault/filter.xmlui.apps/src/main/content/META-INF/vault/filter.xmlを比較して、各モジュールで管理される異なるノードを理解します。

このページ