SPA コンポーネントを AEM コンポーネントへのマッピング map-components
- ヘッドレスコンテンツを視覚的に編集するユニバーサルエディター。
- ヘッドレスコンテンツをフォームベースで編集するコンテンツフラグメントエディター。
AEM SPA エディター JS SDK を使用して Angular コンポーネントを Adobe Experience Manager(AEM)コンポーネントにマッピングする方法について説明します。コンポーネントマッピングを使用すると、AEM SPA エディター内で、従来の AEM オーサリングと同様に、SPA コンポーネントを動的に更新できます。
この章では、AEM JSON モデル API について詳しく説明し、AEM コンポーネントによって公開された JSON コンテンツを prop として Angular コンポーネントに自動的に挿入する方法についても説明します。
目的
- AEM コンポーネントを SPA コンポーネントにマッピングする方法について説明します。
- コンテナ コンポーネントと コンテンツ コンポーネントの違いを理解します。
- 既存の AEM コンポーネントにマッピングされる新規の Angular コンポーネントを作成します。
作成する内容
この章では、提供されたText SPA コンポーネントが AEM Text コンポーネントにどのようにマッピングされるかを調べます。SPA で使用し AEM でオーサリングできる新規の Image SPA コンポーネントが作成されます。レイアウトコンテナ および テンプレートエディター ポリシーの標準機能を使用して、わずかに外観が異なるビューを作成することもできます。
前提条件
ローカル開発環境の設定に必要なツールと手順を確認します。
コードの取得
-
このチュートリアルの出発点となるものを Git からダウンロードします。
code language-shell $ git clone git@github.com:adobe/aem-guides-wknd-spa.git $ cd aem-guides-wknd-spa $ git checkout Angular/map-components-start -
Maven を使用してコードベースをローカルの AEM インスタンスにデプロイします。
code language-shell $ mvn clean install -PautoInstallSinglePackageAEM 6.x を使用する場合、次の
classicプロファイルを追加します。code language-shell $ mvn clean install -PautoInstallSinglePackage -Pclassic
完成したコードは、GitHub で確認するか、またはブランチ Angular/map-components-solution に切り替えてコードをローカルで確認します。
マッピングアプローチ
基本的な概念は、SPA コンポーネントを AEM コンポーネントにマッピングすることです。AEM コンポーネントは、サーバーサイドで実行され、JSON モデル API の一部としてコンテンツを書き出します。JSON コンテンツは、ブラウザーでクライアントサイドを実行している SPA によって使用されます。SPA コンポーネントと AEM コンポーネントの間に 1 対 1 のマッピングが作成されます。
AEM コンポーネントから Angular コンポーネントへのマッピングの概要
テキストコンポーネントを検査する
AEM プロジェクトアーキタイプは、AEM テキストコンポーネントにマッピングされる Text コンポーネントを提供します。これは、AEM から コンテンツ をレンダリングするという、コンテンツ コンポーネントの例です。
コンポーネントの動作を見てみましょう。
JSON モデルを調べる
-
SPA のコードを調べる前に、AEM が提供する JSON モデルを理解しておくことが重要です。 コアコンポーネントライブラリに移動し、テキストコンポーネントのページを表示します。コアコンポーネントライブラリには、すべての AEM コアコンポーネントの例が記載されています。
-
例の 1 つである JSON タブを選択します。
text、richText、および:typeの 3 つのプロパティが表示されます。:typeは、AEM コンポーネントのsling:resourceType(またはパス)をリストする予約済みのプロパティです。:typeの値は、AEM コンポーネントを SPA コンポーネントにマップするために使用されるものです。textおよびrichTextは、SPA コンポーネントに公開される追加のプロパティです。
テキストコンポーネントの検査
-
新しいターミナルウィンドウを開き、プロジェクト内の
ui.frontendフォルダーに移動します。npm installの後にnpm startを実行して、webpack 開発サーバー を起動します。code language-shell $ cd ui.frontend $ npm run start:mockui.frontendモジュールは現在、モック JSON モデルを使用するように設定されています。 -
新しいブラウザーウィンドウが開いて、http://localhost:4200/content/wknd-spa-angular/us/en/home.html に移動します。
-
任意の IDE で、WKND SPA 用の AEM プロジェクトを開きます。
ui.frontendモジュールを展開し、ui.frontend/src/app/components/text/text.component.tsの下の text.component.ts ファイルを開きます。
-
最初に検査する領域は、35 行目までの
class TextComponentです。code language-js 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() デコレーターは、先ほど確認した、マッピング済み JSON オブジェクトを通じて値が設定されるフィールドの宣言に使用されます。
@HostBinding('innerHtml') get content()は、this.textの値から作成したテキストコンテンツを公開するメソッドです。コンテンツが(this.richTextフラグで決まる)リッチテキストの場合、Angular の組み込みセキュリティは無視されます。Angular の DomSanitizer は、未処理の HTMLを「スクラブ」し、クロスサイトスクリプティングの脆弱性を防ぐために使用されます。このメソッドは、@HostBinding デコレーターを使用してinnerHtmlプロパティにバインドされます。 -
次に、24 行目までの
TextEditConfigを調べます。code language-js const TextEditConfig = { emptyLabel: 'Text', isEmpty: cqModel => !cqModel || !cqModel.text || cqModel.text.trim().length < 1 };上記のコードは AEM オーサー環境で、プレースホルダーをレンダリングするタイミングを決定する役割を果たします。 この
isEmptyメソッドが true を返した場合、プレースホルダーがレンダリングされます。 -
最後に、53 行目までの
MapTo呼び出しを確認します。code language-js MapTo('wknd-spa-angular/components/text')(TextComponent, TextEditConfig );MapTo は、AEM SPA エディター JS SDK(
@adobe/cq-angular-editable-components)から提供されます。パスwknd-spa-angular/components/textは、AEM コンポーネントのsling:resourceTypeを表します。このパスは、前に確認した JSON モデルによって公開された:typeと一致します。MapTo は JSON モデルの応答を解析し、正しい値を SPA コンポーネントの@Input()変数に渡します。AEM
Textコンポーネントの定義はui.apps/src/main/content/jcr_root/apps/wknd-spa-angular/components/textにあります。 -
ui.frontend/src/mocks/json/en.model.jsonの en.model.json を変更して実験します。62 行目までで、
H1およびuタグを使用するように最初のText値を更新します。code language-json "text": { "text": "<h1><u>Hello World!</u></h1>", "richText": true, ":type": "wknd-spa-angular/components/text" }ブラウザーに戻り、webpack 開発サーバー から提供される効果を確認します。
richTextプロパティを true と false の間で切り替えて、動作中のレンダリングロジックを確認します。 -
ui.frontend/src/app/components/text/text.component.htmlの text.component.html を調べます。コンポーネントのコンテンツ全体が
innerHTMLプロパティで設定されるので、このファイルは空です。 -
ui.frontend/src/app/app.module.tsの app.module.ts を調べます。code language-js @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 エディター JS SDK から提供される AEMResponsiveGridComponent を通じて動的に組み込まれます。したがって、app.module.ts の entryComponents 配列にリストされている必要があります。
画像コンポーネントの作成
次に、AEM の画像コンポーネントにマッピングされる Image Angular コンポーネントを作成します。この Image コンポーネントは、コンテンツ コンポーネントのもう一つの例です。
JSO の検査
SPA コードを調べる前に、AEM が指定した JSON モデルを調べます。
-
コアコンポーネントライブラリに置かれた画像の例に移動します。
src、alt、titleのプロパティは、SPAImageコンポーネントの入力に使用されます。note note NOTE 公開された他の画像プロパティ( lazyEnabled、widths)があり、これを使用して開発者は、適応型の遅延読み込みコンポーネントを作成することができます。このチュートリアルで作成されたコンポーネントはシンプルで、これらの詳細なプロパティを使用 しません。 -
IDE に戻り、
en.model.json(ui.frontend/src/mocks/json/en.model.json)を開きます。これはプロジェクトのまったく新しいコンポーネントなので、画像 JSON の「モック」を作成する必要があります。70 行目までで、
imageモデルの JSON エントリを追加し(2 番目のtext_386303036の後にコンマ,を入れることを忘れないでください)、:itemsOrder配列を更新します。code language-json ... ":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" ],このプロジェクトには、webpack 開発サーバー と共に使用されるサンプル画像(
/mock-content/adobestock-140634652.jpeg)が含まれています。すべての en.model.json については、こちらを参照してください。
-
コンポーネントに表示するストック写真を追加します。
ui.frontend/src/mocksの下に images という名前の新しいフォルダーを作成します。adobestock-140634652.jpeg をダウンロードし、新しく作成した images フォルダーに格納します。必要に応じて、自分の画像を自由に使用できます。
画像コンポーネントの実装
-
webpack 開発サーバー が起動されていれば停止します。
-
ui.frontendフォルダー内から Angular CLIng generate componentコマンドを実行して、新しい画像コンポーネントを作成します。code language-shell $ ng generate component components/image -
IDE で、image.component.ts(
ui.frontend/src/app/components/image/image.component.ts)を開いて、次のように更新します。code language-js 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は、srcプロパティに値が設定されているかどうかに応じて、AEM でオーサープレースホルダーをレンダリングするかどうかを決定するための設定です。src、altおよびtitleの@Input()は、JSON API からマッピングされるプロパティです。hasImage()は、画像をレンダリングするかどうかを指定するメソッドです。MapToは、SPA コンポーネントを、ui.apps/src/main/content/jcr_root/apps/wknd-spa-angular/components/imageにある AEM コンポーネントにマッピングします。 -
image.component.html を開いて、次のように更新します。
code language-html <ng-container *ngIf="hasImage"> <img class="image" [src]="src" [alt]="alt" [title]="title"/> </ng-container>これにより、
hasImageが true を返す場合、<img>要素がレンダリングされるようになります。 -
image.component.scss を開いて、次のように更新します。
code language-scss :host-context { display: block; } .image { margin: 1rem 0; width: 100%; border: 0; }note note NOTE :host-contextルールは、AEM SPA エディターのプレースホルダーが正しく機能するために 重要 です。AEM ページエディターで作成するすべての SPA コンポーネントには、少なくともこのルールが必要です。 -
app.module.tsを開いて、entryComponents配列にImageComponentを追加します。code language-js entryComponents: [TextComponent, PageComponent, ImageComponent],TextComponentと同様に、ImageComponentは動的に読み込まれるので、entryComponents配列に含める必要があります。 -
webpack 開発サーバー を起動して、
ImageComponentがレンダリングされることを確認します。code language-shell $ npm run start:mock
SPA に追加された画像
note note NOTE ボーナスチャレンジ: titleの値を画像の下のキャプションとして表示する新しいメソッドを実装します。
AEM でのポリシーの更新
ImageComponent コンポーネントは、webpack 開発サーバー でのみ表示されます。次に、更新された SPA を AEM にデプロイし、テンプレートポリシーを更新します。
-
webpack 開発サーバー を停止し、プロジェクトの ルート から、Maven スキルを使用して変更内容を AEM にデプロイします。
code language-shell $ cd aem-guides-wknd-spa $ mvn clean install -PautoInstallSinglePackage -
AEM 開始画面から、ツール/テンプレート/WKND SPA Angular に移動します。
SPA ページ を選択して編集します。
-
レイアウトコンテナ を選択し、「ポリシー」アイコンをクリックしてポリシーを編集します。
-
許可されたコンポーネント/WKND SPA Angular - コンテンツ の下で、画像 コンポーネントにチェックを入れます。
デフォルトのコンポーネント/マッピングを追加 の下で、画像 - WKND SPA Angular - コンテンツ コンポーネントを選択します。
image/*の mime タイプ を入力します。「完了」をクリックして、ポリシーの更新を保存します。
-
レイアウトコンテナ で、テキスト コンポーネント用の ポリシー アイコンをクリックします。
WKND SPA テキスト という名前の新しいポリシーを作成します。プラグイン/書式設定 の下にあるすべてのボックスをオンにして、次の追加の書式設定オプションを有効にします。
プラグイン/段落スタイル の下で、「段落スタイルを有効にする」チェックボックスをオンにします。
「完了」をクリックしてポリシーの更新を保存します。
-
ホームページ http://localhost:4502/editor.html/content/wknd-spa-angular/us/en/home.html に移動します。
また、
Textコンポーネントを編集して、全画面表示 モードで追加の段落スタイルを追加できます。
-
また、画像を アセットファインダー からドラッグ&ドロップできます。
-
AEM Assets を介して独自の画像を追加するか、標準の WKND 参照サイトの完成したコードベースをインストールします。WKND 参照サイトには、WKND SPAで再利用できる画像が多数含まれています。 パッケージは、AEM のパッケージマネージャーを使用してインストールできます。
レイアウトコンテナを調べる
レイアウトコンテナ のサポートは、AEM SPA Editor SDK によって自動的に提供されます。 レイアウトコンテナ は、その名前が示すように コンテナ コンポーネントです。コンテナコンポーネントは、他の コンポーネントを表す JSON 構造を受け入れ、それらを動的にインスタンス化するコンポーネントです。
ここでは、レイアウトコンテナをさらに詳しく調べます。
-
IDE で
ui.frontend/src/app/components/responsive-gridの responsive-grid.component.ts を開きます。code language-js import { AEMResponsiveGridComponent,MapTo } from '@adobe/cq-angular-editable-components'; MapTo('wcm/foundation/components/responsivegrid')(AEMResponsiveGridComponent);AEMResponsiveGridComponentはAEM SPA Editor SDK の一部として実装され、import-componentsを介してプロジェクトに含まれます。 -
ブラウザーで、http://localhost:4502/content/wknd-spa-angular/us/en.model.json に移動します。
レイアウトコンテナ コンポーネントの
sling:resourceTypeはwcm/foundation/components/responsivegridであり、TextコンポーネントやImageコンポーネントと同様に、:typeプロパティを使用して SPA エディターによって認識されます。レイアウトモードを使用してコンポーネントのサイズを変更するのと同じ機能が、SPA エディターで利用できます。
-
http://localhost:4502/editor.html/content/wknd-spa-angular/us/en/home.html に戻ります。さらに 画像 コンポーネントを追加し、レイアウト オプションを使用してサイズを変更してみてください。
-
JSON モデル http://localhost:4502/content/wknd-spa-angular/us/en.model.json を再度開いて、
columnClassNamesが JSON の一部であることを確認してください。
クラス名
aem-GridColumn--default--4は、12 列のグリッドに基づいて幅が 4 列に設定されている必要があることを示します。レスポンシブグリッドについて詳しくは、こちらをご覧ください。 -
IDE に戻り、
ui.appsモジュールで、ui.apps/src/main/content/jcr_root/apps/wknd-spa-angular/clientlibs/clientlib-gridで定義されたクライアントサイドライブラリがあります。less/grid.lessファイルを開きます。このファイルは、レイアウトコンテナ で使用されるブレークポイント(
default、tablet、phone)を特定します。このファイルは、プロジェクトの仕様に応じてカスタマイズされます。 現在、ブレークポイントは1200pxおよび650pxに設定されています。 -
Textコンポーネントのレスポンシブ機能と、更新されたリッチテキストポリシーを使用して、次のようなビューを作成できます。
おめでとうございます。 congratulations
これで、SPA コンポーネントを AEM コンポーネントにマッピングする方法を学習し、新しい Image コンポーネントを実装しました。また、レイアウトコンテナ のレスポンシブ機能について探索する機会もありました。
完成したコードを GitHub で確認する、または、ブランチ Angular/map-components-solution に切り替えて、コードをローカルでチェックアウトします。
次の手順 next-steps
ナビゲーションとルーティング - SPA Editor SDK を使用して AEM ページにマッピングすることで、SPA の複数のビューをサポートする方法について説明します。 Angular ルートを使用して動的ナビゲーションを実装し、既存のヘッダーコンポーネントに追加します。
(ボーナス)ソースコントロールに対する設定の保持 bonus
多くの場合、特に AEM プロジェクトの開始時に、テンプレートや関連するコンテンツポリシーなどの設定をソースコントロールに保持すると便利です。 これにより、すべての開発者が同じセットのコンテンツと設定に対して作業することが保証され、環境間の一貫性がさらに確保できます。プロジェクトが一定の成熟度に達すると、テンプレートの管理作業を特別なパワーユーザーグループに引き継ぐことができます。
次のいくつかの手順は、Visual Studio Code IDE と VSCode AEM Sync を使用して行われますが、AEM のローカルインスタンスからコンテンツを 取り込み または 読み込む ように設定した任意のツールと IDE を使用して行うことができます。
-
Visual Studio Code IDE で、Marketplace 拡張機能を介して VSCode AEM Sync がインストールされていることを確認します。
-
プロジェクトエクスプローラー内の ui.content モジュールをを展開して、
/conf/wknd-spa-angular/settings/wcm/templatesに移動します。 -
templatesフォルダーを 右クリック し、AEM サーバーから読み込み を選択します。
-
コンテンツを読み込む手順を繰り返しますが、
/conf/wknd-spa-angular/settings/wcm/policiesに置かれた ポリシー フォルダーを選択します。 -
ui.content/src/main/content/META-INF/vault/filter.xmlにあるfilter.xmlファイルを調べます。code language-xml <!--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.xmlとui.apps/src/main/content/META-INF/vault/filter.xmlを比較して、各モジュールによって管理される様々なノードを理解します。