SPAの複合コンポーネント

複合コンポーネントは、複数のベースコンポーネントを1つのコンポーネントに組み合わせることで、AEMコンポーネントのモジュラー性を活用します。 一般的な複合コンポーネントの使用例は、画像コンポーネントとテキストコンポーネントの組み合わせで構成されるカードコンポーネントです。

複合コンポーネントがAEMシングルページアプリケーション(SPA)エディターフレームワーク内で適切に実装されている場合、コンテンツ作成者は、そのようなコンポーネントを他のコンポーネントと同様にドラッグ&ドロップできますが、複合コンポーネントを構成する各コンポーネントを個別に編集できます。

この記事では、AEM SPA Editorとシームレスに連携する複合コンポーネントをシングルページアプリケーションに追加する方法について説明します。

ユースケース

この記事では、一般的なカードコンポーネントを使用例として使用します。 カードは、多くのデジタルエクスペリエンスに共通のUI要素で、通常は画像と関連するテキストまたはキャプションで構成されます。 作成者は、カード全体をドラッグ&ドロップできるようにしたいが、カードの画像を個別に編集したり、関連するテキストをカスタマイズしたりできます。

前提条件

複合コンポーネントの使用例をサポートする次のモデルでは、次の前提条件が必要です。

  • AEM開発インスタンスは、サンプルプロジェクトを使用して、ポート4502上でローカルに実行されています。
  • AEMでの編集が有効な外部Reactアプリが作業中です。
  • Reactアプリは、RemotePageコンポーネントを使用してAEMエディターに読み込まれます。

複合コンポーネントをSPAに追加する

AEM内のSPA実装に応じて、複合コンポーネントを実装するための3つの異なるモデルがあります。

以下の節では、カードコンポーネントを例として使用して各ケースを実装する例を示します。

コンポーネントはAEMプロジェクトに存在しません。

まず、合成コンポーネントを構成するコンポーネント(画像とそのテキストのコンポーネント)を作成します。

  1. AEMプロジェクトにテキストコンポーネントを作成します。

  2. 対応するresourceTypeをコンポーネントのeditConfigノードのプロジェクトから追加します。

     resourceType: 'wknd-spa/components/text' 
    
  3. withMappableヘルパーを使用して、コンポーネントの編集を有効にします。

    export const AEMText = withMappable(Text, TextEditConfig); 
    

テキストコンポーネントは次のようになります。

import React from 'react';
import { withMappable } from '@adobe/aem-react-editable-components';

export const TextEditConfig = {
  emptyLabel: 'Text',
  isEmpty: function(props) {
    return !props || !props.text || props.text.trim().length < 1;
  },
  resourceType: 'wknd-spa/components/text'
};

export const Text = ({ cqPath, richText, text }) => {
  const richTextContent = () => (
    <div className="aem_text"
      id={cqPath.substr(cqPath.lastIndexOf('/') + 1)}
      data-rte-editelement
      dangerouslySetInnerHTML={{__html: text}} />
  );
  return richText ? richTextContent() : (
     <div className="aem_text">{text}</div>
  );
};

export const AEMText = withMappable(Text, TextEditConfig);

同様の方法で画像コンポーネントを作成した場合は、画像コンポーネントとテキストコンポーネントを子として使用し、AEMTextコンポーネントと組み合わせて新しいカードコンポーネントにすることができます。

import React from 'react';
import { AEMText } from './AEMText';
import { AEMImage } from './AEMImage';

export const AEMCard = ({ pagePath, itemPath}) => (
  <div>
    <AEMText
       pagePath={pagePath}
       itemPath={`text`} />
    <AEMImage
       pagePath={pagePath}
       itemPath={`image`} />
   </div>
);

この合成コンポーネントは、アプリ内の任意の場所に配置でき、がSPAエディターでテキストと画像コンポーネントのプレースホルダーを追加します。 以下のサンプルでは、カードコンポーネントがタイトルの下のホームコンポーネントに追加されています。

function Home() {
  return (
    <div className="Home">
      <h2>Current Adventures</h2>
      <AEMCard
        pagePath='/content/wknd-spa/home' />
    </div>
  );
}

これにより、エディターでテキストと画像の空のプレースホルダーが表示されます。 エディターを使用してこれらの値を入力すると、指定されたページパス(ルートレベルの/content/wknd-spa/homeに、itemPathで指定された名前で格納)に格納されます。

エディター内の複合カードコンポーネント

コンポーネントはAEMプロジェクトに存在しますが、必要なコンテンツは存在しません。

この場合、カードコンポーネントは、タイトルと画像ノードを含むAEMプロジェクトに既に作成されています。 子ノード(テキストと画像)には、対応するリソースタイプが含まれます。

カードコンポーネントのノード構造

その後、それをSPAに追加して、そのコンテンツを取得できます。

  1. このに対応するコンポーネントをSPAに作成します。 子コンポーネントが、SPAプロジェクト内の対応するAEMリソースタイプにマッピングされていることを確認します。 この例では、前の例で説明したと同じAEMTextコンポーネントとAEMImageコンポーネントを使用します。

    import React from 'react';
    import { Container, withMappable, MapTo } from '@adobe/aem-react-editable-components';
    import { Text, TextEditConfig } from './AEMText';
    import Image, { ImageEditConfig } from './AEMImage';
    
    export const AEMCard = withMappable(Container, {
      resourceType: 'wknd-spa/components/imagecard'
    });
    
    MapTo('wknd-spa/components/text')(Text, TextEditConfig);
    MapTo('wknd-spa/components/image')(Image, ImageEditConfig);
    
  2. imagecardコンポーネントのコンテンツがないので、ページにカードを追加します。 AEMの既存のコンテナをSPAに含めます。

    • AEMプロジェクトに既にコンテナが存在する場合は、代わりにSPAにコンテナを含め、代わりにAEMからコンテナにコンポーネントを追加できます。
    • カードコンポーネントが、SPAの対応するリソースタイプにマッピングされていることを確認します。
    <ResponsiveGrid
     pagePath='/content/wknd-spa/home'
     itemPath='root/responsivegrid' />
    
  3. 作成したwknd-spa/components/imagecardコンポーネントを、ページテンプレート内のコンテナコンポーネントに使用できるコンポーネントに追加します。

これで、imagecardコンポーネントをAEMエディターでコンテナに直接追加できます。

エディター内のコンポジットカード

コンポーネントとその必要なコンテンツは共にAEMプロジェクトに存在します。

コンテンツがAEMに存在する場合は、コンテンツへのパスを指定して、SPAに直接含めることができます。

<AEMCard
    pagePath='/content/wknd-spa/home'
    itemPath='root/responsivegrid/imagecard' />

ノード構造内の複合パス

AEMCardコンポーネントは、前の使用例で定義したと同じです。 ここでは、AEMプロジェクトの上記の場所で定義されたコンテンツがSPAに含まれます。

このページ