SPA コンポーネントを AEM コンポーネントへのマッピング map-components
AEM SPA Editor JS SDK を使用して、React コンポーネントを Adobe Experience Manager(AEM)コンポーネントにマッピングする方法について説明します。コンポーネントマッピングを使用すると、AEM SPA エディター内で、従来の AEM オーサリングと同様に、SPA コンポーネントを動的に更新できます。
この章では、AEM JSON モデル API について詳しく説明し、AEM コンポーネントによって公開された JSON コンテンツを prop として React コンポーネントに自動的に挿入する方法についても説明します。
目的
- AEM コンポーネントを SPA コンポーネントにマッピングする方法について説明します。
- React コンポーネントが AEM から渡された動的プロパティをどのように使用するかを調べます。
- 標準搭載の React AEM コアコンポーネントの使用方法を学びます。
作成する内容
この章では、提供されたText
SPA コンポーネントが AEM Text
コンポーネントにどのようにマッピングされるかを調べます。Image
SPA コンポーネントなどの React コアコンポーネントは、SPA で使用され、AEM でオーサリングされます。レイアウトコンテナ および テンプレートエディター ポリシーの標準機能を使用して、わずかに外観が異なるビューを作成することもできます。
前提条件
ローカル開発環境の設定に必要なツールと手順を確認してください。この章は、SPA の統合の章の続きですが、SPA 対応の AEM プロジェクトさえあれば内容についていくことができます。
マッピングアプローチ
基本的な概念は、SPA コンポーネントを AEM コンポーネントにマッピングすることです。AEM コンポーネントは、サーバーサイドで実行され、JSON モデル API の一部としてコンテンツを書き出します。JSON コンテンツは、ブラウザーでクライアントサイドを実行している SPA によって使用されます。SPA コンポーネントと AEM コンポーネントの間に 1 対 1 のマッピングが作成されます。
AEM コンポーネントと React コンポーネントのマッピングの概要
テキストコンポーネントを検査する
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 コンポーネントに公開される追加のプロパティです。 -
JSON 出力を http://localhost:4502/content/wknd-spa-react/us/en.model.json に表示します。次のようなエントリが見つかるはずです。
code language-json "text": { "id": "text-a647cec03a", "text": "<p>Hello World! Updated content!</p>\r\n", "richText": true, ":type": "wknd-spa-react/components/text", "dataLayer": {} }
テキスト SPA コンポーネントを検査する
-
任意の IDE で、SPA の AEM プロジェクトを開きます。
ui.frontend
モジュールを展開し、ui.frontend/src/components/Text/Text.js
の下のText.js
ファイルを開きます。 -
最初に検査する領域は、40 行目までの
class Text
です。code language-js class Text extends Component { get richTextContent() { return (<div id={extractModelId(this.props.cqPath)} data-rte-editelement dangerouslySetInnerHTML={{__html: DOMPurify.sanitize(this.props.text)}} /> ); } get textContent() { return <div>{this.props.text}</div>; } render() { return this.props.richText ? this.richTextContent : this.textContent; } }
Text
は、標準の React コンポーネントです。 コンポーネントはthis.props.richText
を使用して、レンダリングするコンテンツがリッチテキストかプレーンテキストかを判断します。使用される実際の「コンテンツ」はthis.props.text
に由来します。潜在的な XSS 攻撃を避けるために、dangerouslySetInnerHTML を使用してコンテンツをレンダリングする前に、リッチテキストは
DOMPurify
を経由してエスケープされます。演習の前半で JSON モデルから取得したrichText
およびtext
のプロパティです。 -
次に
ui.frontend/src/components/import-components.js
を開き、TextEditConfig
の 86 行目までを確認します。code language-js const TextEditConfig = { emptyLabel: 'Text', isEmpty: function(props) { return !props || !props.text || props.text.trim().length < 1; } };
上記のコードは AEM オーサー環境で、プレースホルダーをレンダリングするタイミングを決定する役割を果たします。 この
isEmpty
メソッドが true を返した場合、プレースホルダーがレンダリングされます。 -
最後に、94 行目までの
MapTo
呼び出しを確認します。code language-js export default MapTo('wknd-spa-react/components/text')(LazyTextComponent, TextEditConfig);
MapTo
は、AEM SPA Editor JS SDK(@adobe/aem-react-editable-components
)によって指定されます。パスwknd-spa-react/components/text
は、AEM コンポーネントのsling:resourceType
を表します。このパスは、前に確認した JSON モデルによって公開された:type
と一致します。MapTo
は JSON モデルの応答を解析し、正しい値をprops
として SPA コンポーネントに渡します。AEM
Text
コンポーネントの定義はui.apps/src/main/content/jcr_root/apps/wknd-spa-react/components/text
にあります。
React コアコンポーネントの使用
AEM WCM コンポーネント - React コア実装 および AEM WCM コンポーネント - Spa エディター - React コア実装。これらは、すぐに使用できる AEM コンポーネントのセットにマッピングされる、再利用可能な UI コンポーネントです。 ほとんどのプロジェクトでは、これらのコンポーネントを、独自の実装の出発点として再利用できます。
-
プロジェクトコードで、
ui.frontend/src/components
にあるファイルimport-components.js
を開きます。
このファイルは、AEM コンポーネントにマッピングされているすべての SPA コンポーネントを読み込みます。 SPA エディター実装の動的な特性を考慮すると、作成可能な AEM コンポーネントに関連付けられているすべての SPA コンポーネントを明示的に参照する必要があります。 これにより AEM オーサーは、アプリケーション内の任意の場所におけるコンポーネントの使用を選択することができます。 -
以下の import ステートメントには、プロジェクトで記述された SPA コンポーネントが含まれています。
code language-js import './Page/Page'; import './Text/Text'; import './Container/Container'; import './ExperienceFragment/ExperienceFragment';
-
@adobe/aem-core-components-react-spa
と@adobe/aem-core-components-react-base
から、他のいくつかのimports
があります。これらは、React コアコンポーネントを読み込んで、現在のプロジェクトで使用できるようにします。これらは前述のText
コンポーネントの例と同様に、MapTo
を使用してプロジェクト固有の AEM コンポーネントにマッピングされます。
AEM ポリシーの更新
ポリシーは AEM テンプレートの機能であり、開発者やパワーユーザーが、どのコンポーネントを使用できるかを細かく制御できます。React コアコンポーネントは SPA コードに含まれていますが、アプリケーションで使用する前に、ポリシーを介して有効にする必要があります。
-
AEM 開始画面から、ツール/テンプレート/WKND SPA React に移動します。
-
SPA ページ 編集用テンプレートを選択して、開きます。
-
レイアウトコンテナ を選択し、「ポリシー」アイコンをクリックしてポリシーを編集します。
-
許可されたコンポーネント/WKND SPA React - コンテンツ/画像 の下で、ティーザー および タイトル を検査します。
デフォルトのコンポーネント/マッピングを追加 の下で、 画像 - WKND SPA React - コンテンツ コンポーネントを選択します。
image/*
の mime タイプ を入力します。「完了」をクリックして、ポリシーの更新を保存します。
-
レイアウトコンテナ 内の テキスト コンポーネント用の「ポリシー」アイコンをクリックします。
WKND SPA テキスト という名前の新しいポリシーを作成します。プラグイン/書式設定 の下にあるすべてのボックスをオンにして、次の追加の書式設定オプションを有効にします。
プラグイン/段落スタイル の下で、「段落スタイルを有効にする」チェックボックスをオンにします。
「完了」をクリックしてポリシーの更新を保存します。
作成者コンテンツ
-
ホームページ http://localhost:4502/editor.html/content/wknd-spa-react/us/en/home.htmlに移動します。
-
これで、ページで追加の 画像、ティーザー、タイトル 各コンポーネントを使用できるようになります。
-
また、
Text
コンポーネントを編集して、全画面表示 モードで追加の段落スタイルを追加できます。 -
また、画像を アセットファインダー からドラッグ&ドロップできます。
-
タイトル コンポーネントおよび ティーザー コンポーネントで実験してください。
-
AEM Assets を介して独自の画像を追加するか、標準の WKND 参照サイトの完成したコードベースをインストールします。WKND 参照サイトには、WKND SPAで再利用できる画像が多数含まれています。 パッケージは、AEM のパッケージマネージャーを使用してインストールできます。
レイアウトコンテナを調べる
レイアウトコンテナ のサポートは、AEM SPA Editor SDK によって自動的に提供されます。 レイアウトコンテナ は、その名前が示すように コンテナ コンポーネントです。コンテナコンポーネントは、他の コンポーネントを表す JSON 構造を受け入れ、それらを動的にインスタンス化するコンポーネントです。
ここでは、レイアウトコンテナをさらに詳しく調べます。
-
ブラウザーで、http://localhost:4502/content/wknd-spa-react/us/en.model.json に移動します。
レイアウトコンテナ コンポーネントの
sling:resourceType
はwcm/foundation/components/responsivegrid
であり、Text
コンポーネントやImage
コンポーネントと同様に、:type
プロパティを使用して SPA エディターによって認識されます。レイアウトモードを使用してコンポーネントのサイズを変更するのと同じ機能が、SPA エディターで利用できます。
-
http://localhost:4502/editor.html/content/wknd-spa-react/us/en/home.html に戻ります。さらに 画像 コンポーネントを追加し、レイアウト オプションを使用してサイズを変更してみてください。
-
JSON モデル http://localhost:4502/content/wknd-spa-react/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-react/clientlibs/clientlib-grid
で定義されたクライアントサイドライブラリがあります。less/grid.less
ファイルを開きます。このファイルは、レイアウトコンテナ で使用されるブレークポイント(
default
、tablet
、phone
)を特定します。このファイルは、プロジェクトの仕様に応じてカスタマイズされます。 現在、ブレークポイントは1200px
および768px
に設定されています。 -
Text
コンポーネントのレスポンシブ機能と、更新されたリッチテキストポリシーを使用して、次のようなビューを作成できます。
おめでとうございます。 congratulations
これで、SPA コンポーネントを AEM コンポーネントにマッピングする方法を学習し、React コアコンポーネントを使用しました。 また、レイアウトコンテナ のレスポンシブ機能について探索する機会もありました。
次の手順 next-steps
ナビゲーションとルーティング - SPA Editor SDK を使用して AEM ページにマッピングすることで、SPA の複数のビューをサポートする方法について説明します。 動的ナビゲーションは、React Router と React Core Components を使用して実装されています。
(ボーナス)ソースコントロールに対する設定の保持 bonus-configs
多くの場合、特に AEM プロジェクトの開始時に、テンプレートや関連するコンテンツポリシーなどの設定をソースコントロールに保持すると便利です。 これにより、すべての開発者が同じセットのコンテンツと設定に対して作業することが保証され、環境間の一貫性がさらに確保できます。プロジェクトが一定の成熟度に達すると、テンプレートの管理作業を特別なパワーユーザーグループに引き継ぐことができます。
次のいくつかの手順は、Visual Studio Code IDE と VSCode AEM Sync を使用して行われますが、AEM のローカルインスタンスからコンテンツを 取り込み または 読み込む ように設定した任意のツールと IDE を使用して行うことができます。
-
Visual Studio Code IDE で、Marketplace 拡張機能を介して VSCode AEM Sync がインストールされていることを確認します。
-
プロジェクトエクスプローラー内の ui.content モジュールをを展開して、
/conf/wknd-spa-react/settings/wcm/templates
に移動します。 -
templates
フォルダーを 右クリック し、AEM サーバーから読み込み を選択します。 -
コンテンツを読み込む手順を繰り返しますが、
/conf/wknd-spa-react/settings/wcm/templates/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-react" mode="merge"/> <filter root="/content/wknd-spa-react" mode="merge"/> <filter root="/content/dam/wknd-spa-react" mode="merge"/> <filter root="/content/experience-fragments/wknd-spa-react" 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
を比較して、各モジュールによって管理される様々なノードを理解します。
(ボーナス)カスタム画像コンポーネントの作成 bonus-image
SPA 画像コンポーネントは、React コアコンポーネントによって既に指定されています。 ただし、追加のプラクティスが必要な場合は、AEM 画像コンポーネントにマップする独自の React 実装を作成します。この Image
コンポーネントは、コンテンツ コンポーネントのもう一つの例です。
JSO の検査
SPA コードを調べる前に、AEM が指定した JSON モデルを調べます。
-
コアコンポーネントライブラリに置かれた画像の例に移動します。
src
、alt
、title
のプロパティは、SPAImage
コンポーネントの入力に使用されます。note note NOTE 公開された他の画像プロパティ( lazyEnabled
、widths
)があり、これを使用して開発者は、適応型の遅延読み込みコンポーネントを作成することができます。このチュートリアルで作成されたコンポーネントはシンプルで、これらの詳細なプロパティを使用 しません。
画像コンポーネントの実装
-
次に、
Image
という名前の新しいフォルダーをui.frontend/src/components
の下に作成します。 -
Image
フォルダーの下に、Image.js
という名前の新しいファイルを作成します。 -
次の
import
ステートメントをImage.js
に追加します。code language-js import React, {Component} from 'react'; import {MapTo} from '@adobe/aem-react-editable-components';
-
次に
ImageEditConfig
を追加して、AEM でプレースホルダーを表示するタイミングを決定します。code language-js export const ImageEditConfig = { emptyLabel: 'Image', isEmpty: function(props) { return !props || !props.src || props.src.trim().length < 1; } };
src
プロパティが設定されていない場合、プレースホルダーが表示されます。 -
次に、
Image
クラスを実装します。code language-js export default class Image extends Component { get content() { return <img className="Image-src" src={this.props.src} alt={this.props.alt} title={this.props.title ? this.props.title : this.props.alt} />; } render() { if(ImageEditConfig.isEmpty(this.props)) { return null; } return ( <div className="Image"> {this.content} </div> ); } }
上記のコードは、JSON モデルが渡した props
src
、alt
、title
に基づいて<img>
をレンダリングします。 -
MapTo
コードを追加して、React コンポーネントを AEM コンポーネントにマップします。code language-js MapTo('wknd-spa-react/components/image')(Image, ImageEditConfig);
文字列
wknd-spa-react/components/image
は、ui.apps/src/main/content/jcr_root/apps/wknd-spa-react/components/image
のui.apps
にある AEM コンポーネントの場所に対応していることにご注意ください。 -
同じディレクトリ内に
Image.css
という名前の新しいファイルを作成し、以下を追加します。code language-scss .Image-src { margin: 1rem 0; width: 100%; border: 0; }
-
Image.js
で、import
ステートメントの下の最上部のファイルに、参照を追加します。code language-js import React, {Component} from 'react'; import {MapTo} from '@adobe/aem-react-editable-components'; require('./Image.css');
-
ファイル
ui.frontend/src/components/import-components.js
を開き、新しいImage
コンポーネントに参照を追加します。code language-js import './Page/Page'; import './Text/Text'; import './Container/Container'; import './ExperienceFragment/ExperienceFragment'; import './Image/Image'; //add reference to Image component
-
import-components.js
で、React コアコンポーネント画像をコメントアウトします。code language-js //MapTo('wknd-spa-react/components/image')(ImageV2, {isEmpty: ImageV2IsEmptyFn});
これにより、代わりにカスタム画像コンポーネントが確実に使用されます。
-
プロジェクトのルートから、Maven を使用して SPA コードを AEM にデプロイします。
code language-shell $ cd aem-guides-wknd-spa.react $ mvn clean install -PautoInstallSinglePackage
-
AEM で SPA を検査します。ページ上のすべての画像コンポーネントは引き続き機能するはずです。レンダリングされた出力を調べると、React コアコンポーネントではなく、カスタム画像コンポーネントのマークアップが表示されます。
カスタム画像コンポーネントのマークアップ
code language-html <div class="Image"> <img class="Image-src" src="/content/image-src.jpg"> </div>
React コアコンポーネント画像のマークアップ
code language-html <div class="cmp-image cq-dd-image"> <img src="/content/image-src.jpg" class="cmp-image__image"> </div>
独自のコンポーネントを拡張および実装するための導入に適しています。