ナビゲーションとルーティングの追加

SPA Editor SDKを使用してAEMページにマッピングすることで、SPAの複数のビューをサポートする方法について説明します。 動的なナビゲーションは、React RouterとReactコアコンポーネントを使用して実装されます。

目的

  1. SPA Editorを使用する場合に使用できるSPAモデルのルーティングオプションを理解します。
  2. React Routerを使用して、SPAの異なるビュー間を移動する方法を説明します。
  3. AEM Reactコアコンポーネントを使用して、AEMページ階層に基づく動的なナビゲーションを実装します。

作成する内容

この章では、AEMのSPAにナビゲーションを追加します。 ナビゲーションメニューはAEMページ階層によって駆動され、ナビゲーションコアコンポーネントが提供するJSONモデルを利用します。

ナビゲーションの追加

前提条件

ローカル開発環境の設定に必要なツールと手順を確認します。 この章は、「コンポーネントのマップ」の章の続きですが、必要な操作に従うのは、ローカルのAEMインスタンスにデプロイされるSPA対応のAEMプロジェクトです。

テンプレートへのナビゲーションの追加

  1. ブラウザーを開き、 AEM http://localhost:4502/にログインします。 開始コードベースは、既にデプロイされている必要があります。

  2. SPA Page Template​に移動します。http://localhost:4502/editor.html/conf/wknd-spa-react/settings/wcm/templates/spa-page-template/structure.html.

  3. 最も外側にある​ルートレイアウトコンテナ​を選択し、ポリシー​アイコンをクリックします。 オーサリング用に​レイアウトコンテナ​をロック解除して選択する場合は、​に注意してください。

    ルートレイアウトコンテナポリシーアイコンを選択します

  4. SPA Structure​という名前の新しいポリシーを作成します。

    SPA構造ポリシー

    許可されているコンポーネント > 一般 」で、レイアウトコンテナ​コンポーネントを選択します。

    許可されているコンポーネント > WKND SPA REACT - STRUCTURE​の下で、ナビゲーション​コンポーネントを選択します。

    ナビゲーションコンポーネントの選択

    許可されているコンポーネント > WKND SPA REACT - Content​の下で、画像​と​テキスト​コンポーネントを選択します。 合計4つのコンポーネントを選択する必要があります。

    完了」をクリックして、変更を保存します。

  5. ページを更新し、ロックされていない​レイアウトコンテナ​の上に​ナビゲーション​コンポーネントを追加します。

    テンプレートにナビゲーションコンポーネントを追加

  6. ナビゲーション​コンポーネントを選択し、ポリシー​アイコンをクリックして、ポリシーを編集します。

  7. ポリシーのタイトル​を​SPA Navigation​にして、新しいポリシーを作成します。

    プロパティ​の下:

    • ナビゲーションルート​を/content/wknd-spa-react/us/enに設定します。
    • Exclude Root Levels​を​1​に設定します。
    • すべての子ページを収集」のチェックを外します。
    • ナビゲーション構造の深さ​を​3​に設定します。

    ナビゲーションポリシーの構成

    これにより、/content/wknd-spa-react/us/enの下の2レベルのナビゲーションが収集されます。

  8. 変更を保存すると、テンプレートの一部として入力されたNavigationが表示されます。

    入力済みナビゲーションコンポーネント

子ページの作成

次に、AEMで別のビューとして機能する追加のページを作成します。 また、AEMが提供するJSONモデルの階層構造も調べます。

  1. サイト​コンソールに移動します。http://localhost:4502/sites.html/content/wknd-spa-react/us/en/home. WKND SPA Reactホームページ​を選択し、作成 / ページ​をクリックします。

    ページを新規作成

  2. テンプレート」で、「SPAページ」を選択します。 「プロパティ」に、タイトル​に​ページ1​を、名前に​ページ1​を入力します。

    最初のページのプロパティを入力します

    作成」をクリックし、ダイアログポップアップで「開く」をクリックしてAEM SPAエディターでページを開きます。

  3. 新しい​テキスト​コンポーネントをメインの​レイアウトコンテナ​に追加します。 コンポーネントを編集し、次のテキストを入力します。RTEと H2 要素を使用して、ページ1​を作成します。

    サンプルコンテンツページ1

    画像などのコンテンツを自由に追加できます。

  4. AEM Sitesコンソールに戻り、上記の手順を繰り返し、ページ1​の兄弟として​ページ2​という2番目のページを作成します。

  5. 最後に、3番目のページ​ページ3​を、ページ2​の​​として作成します。 完了すると、サイト階層は次のようになります。

    サイト階層のサンプル

  6. ナビゲーションコンポーネントを使用して、SPAの様々な領域に移動できるようになりました。

    ナビゲーションとルーティング

  7. AEM Editorの外部でページを開きます。http://localhost:4502/content/wknd-spa-react/us/en/home.html. ナビゲーション​コンポーネントを使用して、アプリの様々なビューに移動します。

  8. ブラウザーの開発者ツールを使用して、移動中にネットワークリクエストを調べます。 以下のスクリーンショットは、Google Chromeブラウザーからキャプチャされたものです。

    ネットワーク要求の監視

    最初のページ読み込みの後、以降のナビゲーションでは完全なページ更新がおこなわれず、以前に訪問したページに戻る際にネットワークトラフィックが最小限に抑えられることを確認します。

階層ページのJSONモデル

次に、SPAのマルチビューエクスペリエンスを推進するJSONモデルを調べます。

  1. 新しいタブで、AEMが提供するJSONモデルAPIを開きます。http://localhost:4502/content/wknd-spa-react/us/en.model.json. ブラウザー拡張機能を使用してJSON🔗を形式設定すると便利です。

    このJSONコンテンツは、SPAが最初に読み込まれたときにリクエストされます。 外側の構造は次のようになります。

    {
    "language": "en",
    "title": "en",
    "templateName": "spa-app-template",
    "designPath": "/libs/settings/wcm/designs/default",
    "cssClassNames": "spa page basicpage",
    ":type": "wknd-spa-react/components/spa",
    ":items": {},
    ":itemsOrder": [],
    ":hierarchyType": "page",
    ":path": "/content/wknd-spa-react/us/en",
    ":children": {
       "/content/wknd-spa-react/us/en/home": {},
       "/content/wknd-spa-react/us/en/home/page-1": {},
       "/content/wknd-spa-react/us/en/home/page-2": {},
       "/content/wknd-spa-react/us/en/home/page-2/page-3": {}
       }
    }
    

    :childrenの下に、作成された各ページのエントリが表示されます。 すべてのページのコンテンツは、この最初のJSONリクエストに含まれます。 コンテンツは既にクライアント側で使用可能なので、ナビゲーションルーティングを使用すると、SPAの以降のビューがすばやく読み込まれます。

    最初のJSONリクエストでSPAのコンテンツの​ALL​を読み込むと、最初のページ読み込みが遅くなるので、賢明ではありません。 次に、ページの階層の深さを収集する方法を見てみましょう。

  2. 次の場所にある​SPA Root​テンプレートに移動します。http://localhost:4502/editor.html/conf/wknd-spa-react/settings/wcm/templates/spa-app-template/structure.html.

    ページプロパティメニュー / ページポリシー​をクリックします。

    SPA Rootのページポリシーを開きます。

  3. SPA Root​テンプレートには、収集されるJSONコンテンツを制御するための追加の「階層構造」タブがあります。 構造の深さ​は、サイト階層の深さを決定し、ルート​の下の子ページを収集します。 「構造パターン」フィールドを使用して、正規表現に基づいて追加のページを除外することもできます。

    構造の深さ​を​2​に更新します。

    構造の深さの更新

    完了」をクリックして、ポリシーに対する変更を保存します。

  4. JSONモデルhttp://localhost:4502/content/wknd-spa-react/us/en.model.jsonを再度開きます。

    {
    "language": "en",
    "title": "en",
    "templateName": "spa-app-template",
    "designPath": "/libs/settings/wcm/designs/default",
    "cssClassNames": "spa page basicpage",
    ":type": "wknd-spa-react/components/spa",
    ":items": {},
    ":itemsOrder": [],
    ":hierarchyType": "page",
    ":path": "/content/wknd-spa-react/us/en",
    ":children": {
       "/content/wknd-spa-react/us/en/home": {},
       "/content/wknd-spa-react/us/en/home/page-1": {},
       "/content/wknd-spa-react/us/en/home/page-2": {}
       }
    }
    

    ページ3​のパスが削除されていることに注意してください。/content/wknd-spa-react/us/en/home/page-2/page-3を最初のJSONモデルから取得します。 これは、ページ3​が階層のレベル3にあり、レベル2の最大深さのコンテンツのみを含むようにポリシーを更新したからです。

  5. SPAホームページを再度開きます。http://localhost:4502/content/wknd-spa-react/us/en/home.htmlを開き、ブラウザーの開発者ツールを開きます。

    ページを更新すると、SPAルートである/content/wknd-spa-react/us/en.model.jsonへのXHRリクエストが表示されます。 このチュートリアルで既に作成したSPAルートテンプレートの階層の深さ設定に基づいて、3つの子ページのみが含まれています。 ページ3​は含まれません。

    最初のJSONリクエスト — SPA Root

  6. 開発者ツールを開いた状態で、Navigationコンポーネントを使用して​ページ3​に直接移動します。

    新しいXHRリクエストが次の処理に対しておこなわれることを確認します。/content/wknd-spa-react/us/en/home/page-2/page-3.model.json

    3ページ目のXHR要求

    AEM Model Managerは、ページ3​のJSONコンテンツが使用できないことを認識し、追加のXHRリクエストを自動的にトリガーします。

  7. 次の場所に直接移動して、ディープリンクを試してみます。http://localhost:4502/content/wknd-spa-react/us/en/home/page-2.html. また、ブラウザーの「戻る」ボタンが引き続き機能することを確認します。

Inspect React Routing

ナビゲーションとルーティングは、React Routerで実装されます。 React Routerは、Reactアプリケーション用のナビゲーションコンポーネントの集まりです。 AEM Reactコアコンポー ネントは、React Routerの機能を使用して、前の手順で使用し ​たナビゲーションコンポーネントを実装します。

次に、React RouterがSPAと統合されている方法を調べ、React RouterのLinkコンポーネントを使用して実験します。

  1. IDEで、ui.frontend/src/index.jsにあるindex.jsファイルを開きます。

    /* index.js */
    import { Router } from 'react-router-dom';
    ...
    ...
     ModelManager.initialize().then(pageModel => {
        const history = createBrowserHistory();
        render(
        <Router history={history}>
            <App
            history={history}
            cqChildren={pageModel[Constants.CHILDREN_PROP]}
            cqItems={pageModel[Constants.ITEMS_PROP]}
            cqItemsOrder={pageModel[Constants.ITEMS_ORDER_PROP]}
            cqPath={pageModel[Constants.PATH_PROP]}
            locationPathname={window.location.pathname}
            />
        </Router>,
        document.getElementById('spa-root')
        );
    });
    

    Appは、React RouterRouterコンポーネントでラップされます。 AEM SPA Editor JS SDKが提供するModelManagerは、JSONモデルAPIに基づいて、動的ルートをAEMページに追加します。

  2. ui.frontend/src/components/Page/Page.jsにあるPage.jsファイルを開きます。

    class AppPage extends Page {
      get containerProps() {
        let attrs = super.containerProps;
        attrs.className =
          (attrs.className || '') + ' page ' + (this.props.cssClassNames || '');
        return attrs;
      }
    }
    
    export default MapTo('wknd-spa-react/components/page')(
      withComponentMappingContext(withRoute(AppPage))
    );
    

    Page SPAコンポーネントは、MapTo関数を使用して、AEMの​Pages​を対応するSPAコンポーネントにマッピングします。 withRouteユーティリティは、cqPathプロパティに基づいて、SPAを適切なAEMの子ページに動的にルーティングするのに役立ちます。

  3. ui.frontend/src/components/Header/Header.jsHeader.jsコンポーネントを開きます。

  4. Headerを更新して、Link<h1>タグをホームページにラップします。

      //Header.js
      import React, {Component} from 'react';
    + import {Link} from 'react-router-dom';
      require('./Header.css');
    
    export default class Header extends Component {
    
        render() {
            return (
                <header className="Header">
                <div className="Header-container">
    +              <Link to="/content/wknd-spa-react/us/en/home.html">
                        <h1>WKND</h1>
    +              </Link>
                </div>
                </header>
            );
        }
    

    デフォルトの<a>アンカータグを使用する代わりに、React Routerが提供する<Link>を使用します。 to=が有効なルートを指す限り、SPAはそのルートに切り替わり、ではなく、完全なページ更新を実行します。 ここでは、単にホームページへのリンクをハードコード化して、Linkの使用方法を説明します。

  5. App.test.js(ui.frontend/src/App.test.js)のテストを更新します。

    + import { BrowserRouter as Router } from 'react-router-dom';
      import App from './App';
    
      it('renders without crashing', () => {
        const div = document.createElement('div');
    -   ReactDOM.render(<App />, div);
    +   ReactDOM.render(<Router><App /></Router>, div);
      });
    

    App.jsで参照される静的コンポーネント内でReact Routerの機能を使用しているので、単体テストを更新して対応する必要があります。

  6. ターミナルを開き、プロジェクトのルートに移動し、Mavenのスキルを使用してAEMにプロジェクトをデプロイします。

    $ cd aem-guides-wknd-spa.react
    $ mvn clean install -PautoInstallSinglePackage
    
  7. AEMのSPAのいずれかのページに移動します。http://localhost:4502/content/wknd-spa-react/us/en/home/page-1.html

    Navigationコンポーネントを使用して移動する代わりに、Header内のリンクを使用します。

    ヘッダーリンク

    ページ全体の更新が​トリガーされない​で、SPAルーティングが機能していることを確認します。

  8. 必要に応じて、標準の<a>アンカータグを使用してHeader.jsファイルを試します。

    <a href="/content/wknd-spa-react/us/en/home.html">
        <h1>WKND</h1>
    </a>
    

    これは、SPAルーティングと通常のWebページリンクの違いを説明するのに役立ちます。

おめでとうございます。

これで、SPA Editor SDKを使用してAEMページにマッピングすることで、SPAの複数のビューをサポートする方法を学びました。 React Routerを使用してダイナミックナビゲーションが実装され、Headerコンポーネントに追加されました。

このページ