AEM SPA Editor JS SDK を使用して、React コンポーネントを Adobe Experience Manager(AEM)コンポーネントにマッピングする方法について説明します。コンポーネントマッピングを使用すると、AEM SPA エディター内で、従来の AEM オーサリングと同様に、SPA コンポーネントを動的に更新できます。
この章では、AEM JSON モデル API について詳しく説明し、AEM コンポーネントによって公開された JSON コンテンツを prop として React コンポーネントに自動的に挿入する方法についても説明します。
この章では、提供された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 からコンテンツをレンダリングするという、コンテンツコンポーネントの例です。
コンポーネントの動作を見てみましょう。
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 に表示します。次のようなエントリが見つかるはずです。
"text": {
"id": "text-a647cec03a",
"text": "<p>Hello World! Updated content!</p>\r\n",
"richText": true,
":type": "wknd-spa-react/components/text",
"dataLayer": {}
}
任意の IDE で、SPA の AEM プロジェクトを開きます。 ui.frontend
モジュールを展開し、ui.frontend/src/components/Text/Text.js
の下の Text.js
ファイルを開きます。
最初に検査する領域は、40 行目までの class Text
です。
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 行目までを確認します。
const TextEditConfig = {
emptyLabel: 'Text',
isEmpty: function(props) {
return !props || !props.text || props.text.trim().length < 1;
}
};
上記のコードは AEM オーサー環境で、プレースホルダーをレンダリングするタイミングを決定する役割を果たします。 この isEmpty
メソッドが true を返した場合、プレースホルダーがレンダリングされます。
最後に、94 行目までの MapTo
呼び出しを確認します。
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
にあります。
AEM WCM コンポーネント - React コア実装 および AEM WCM コンポーネント - Spa エディター - React コア実装。これらは、すぐに使用できる AEM コンポーネントのセットにマッピングされる、再利用可能な UI コンポーネントです。 ほとんどのプロジェクトでは、これらのコンポーネントを、独自の実装の出発点として再利用できます。
プロジェクトコードで、ui.frontend/src/components
にあるファイル import-components.js
を開きます。
このファイルは、AEM コンポーネントにマッピングされているすべての SPA コンポーネントを読み込みます。 SPA エディター実装の動的な特性を考慮すると、作成可能な AEM コンポーネントに関連付けられているすべての SPA コンポーネントを明示的に参照する必要があります。 これにより AEM オーサーは、アプリケーション内の任意の場所におけるコンポーネントの使用を選択することができます。
以下の import ステートメントには、プロジェクトで記述された SPA コンポーネントが含まれています。
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 テンプレートの機能であり、開発者やパワーユーザーが、どのコンポーネントを使用できるかを細かく制御できます。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
コンポーネントのレスポンシブ機能と、更新されたリッチテキストポリシーを使用して、次のようなビューを作成できます。
これで、SPA コンポーネントを AEM コンポーネントにマッピングする方法を学習し、React コアコンポーネントを使用しました。 また、レイアウトコンテナのレスポンシブ機能について探索する機会もありました。
ナビゲーションとルーティング - SPA Editor SDK を使用して AEM ページにマッピングすることで、SPA の複数のビューをサポートする方法について説明します。 動的ナビゲーションは、React Router と React Core Components を使用して実装されています。
多くの場合、特に 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
ファイルを調べます。
<!--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
を比較して、各モジュールによって管理される様々なノードを理解します。
SPA 画像コンポーネントは、React コアコンポーネントによって既に指定されています。 ただし、追加のプラクティスが必要な場合は、AEM 画像コンポーネントにマップする独自の React 実装を作成します。この Image
コンポーネントは、コンテンツコンポーネントのもう一つの例です。
SPA コードを調べる前に、AEM が指定した JSON モデルを調べます。
コアコンポーネントライブラリに置かれた画像の例に移動します。
src
、alt
、title
のプロパティは、SPA Image
コンポーネントの入力に使用されます。
公開された他の画像プロパティ(lazyEnabled
、widths
)があり、これを使用して開発者は、適応型の遅延読み込みコンポーネントを作成することができます。このチュートリアルで作成されたコンポーネントはシンプルで、これらの詳細なプロパティを使用しません。
次に、Image
という名前の新しいフォルダーを ui.frontend/src/components
の下に作成します。
Image
フォルダーの下に、Image.js
という名前の新しいファイルを作成します。
次の import
ステートメントを Image.js
に追加します。
import React, {Component} from 'react';
import {MapTo} from '@adobe/aem-react-editable-components';
次に ImageEditConfig
を追加して、AEM でプレースホルダーを表示するタイミングを決定します。
export const ImageEditConfig = {
emptyLabel: 'Image',
isEmpty: function(props) {
return !props || !props.src || props.src.trim().length < 1;
}
};
src
プロパティが設定されていない場合、プレースホルダーが表示されます。
次に、Image
クラスを実装します。
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 コンポーネントにマップします。
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
という名前の新しいファイルを作成し、以下を追加します。
.Image-src {
margin: 1rem 0;
width: 100%;
border: 0;
}
Image.js
で、import
ステートメントの下の最上部のファイルに、参照を追加します。
import React, {Component} from 'react';
import {MapTo} from '@adobe/aem-react-editable-components';
require('./Image.css');
ファイル ui.frontend/src/components/import-components.js
を開き、新しい Image
コンポーネントに参照を追加します。
import './Page/Page';
import './Text/Text';
import './Container/Container';
import './ExperienceFragment/ExperienceFragment';
import './Image/Image'; //add reference to Image component
import-components.js
で、React コアコンポーネント画像をコメントアウトします。
//MapTo('wknd-spa-react/components/image')(ImageV2, {isEmpty: ImageV2IsEmptyFn});
これにより、代わりにカスタム画像コンポーネントが確実に使用されます。
プロジェクトのルートから、Maven を使用して SPA コードを AEM にデプロイします。
$ cd aem-guides-wknd-spa.react
$ mvn clean install -PautoInstallSinglePackage
AEM で SPA を検査します。ページ上のすべての画像コンポーネントは引き続き機能するはずです。レンダリングされた出力を調べると、React コアコンポーネントではなく、カスタム画像コンポーネントのマークアップが表示されます。
カスタム画像コンポーネントのマークアップ
<div class="Image">
<img class="Image-src" src="/content/image-src.jpg">
</div>
React コアコンポーネント画像のマークアップ
<div class="cmp-image cq-dd-image">
<img src="/content/image-src.jpg" class="cmp-image__image">
</div>
独自のコンポーネントを拡張および実装するための導入に適しています。