モバイルアプリのページテンプレート page-templates-for-mobile-apps

IMPORTANT
AEM 6.5 の新規インストールでは、AEM Mobile アプリケーション機能はサポートされていません。 AEM でヘッドレスコンテンツの管理に推奨されるエディターは次のようになりました。

モバイルアプリのページテンプレート page-templates-for-mobile-apps-1

アプリ用に作成するページコンポーネントは、/libs/mobileapps/components/angular/ng-page コンポーネント(​ ローカルサーバー上のCRXDE Liteで開く)に基づいています。 このコンポーネントには、コンポーネントが継承またはオーバーライドする次のJSP スクリプトが含まれています。

  • ng-page.jsp
  • head.jsp
  • body.jsp
  • angular-app-module.js.jsp
  • angular-route-fragment.js.jsp
  • angular-app-controllers.js.jsp
  • controller.js.jsp
  • template.jsp
  • angular-module-list.js.jsp
  • header.jsp
  • footer.jsp
  • js_clientlibs.jsp
  • css_clientlibs.jsp

ng-page.jsp ng-page-jsp

applicationName プロパティを使用してアプリケーションの名前を決定し、pageContextを介して公開します。

head.jspとbody.jspが含まれます。

head.jsp head-jsp

アプリページの<head>要素を書き出します。

アプリのビューポートメタプロパティを上書きする場合は、上書きするファイルです。

ベストプラクティスに従って、アプリにはクライアントライブラリのcss部分がヘッドに含まれ、JSはクロージング < body>要素に含まれます。

body.jsp body-jsp

Angular ページの本文は、wcmModeが検出されたか(WCMMode.DISABLED!=)に応じて異なってレンダリングされ、ページがオーサリング用に開かれているか、公開済みページとして開かれているかを判断します。

作成者モード

オーサーモードでは、各ページは個別にレンダリングされます。 Angularでは、ページ間のルーティングは処理されず、ページのコンポーネントを含む部分的なテンプレートを読み込むために使用されるng ビューも使用されません。 代わりに、ページテンプレート(template.jsp)のコンテンツは、cq:include タグを介してサーバーサイドに含まれます。

この方法を使用すると、オーサー機能(段落システム、Sidekick、デザインモードでのコンポーネントの追加や編集など)を変更することなく機能させることができます。 アプリなどのクライアントサイドのレンダリングに依存するページは、AEM オーサーモードでは適切に機能しません。

template.jsp インクルードは、ng-controller ディレクティブを含むdiv要素でラップされます。 この構造により、DOM コンテンツとコントローラとのリンクが可能になる。 したがって、クライアント側で自分自身をレンダリングするページは失敗しますが、そのようなことが起こる個々のコンポーネントは正常に動作します(以下のコンポーネントの節を参照)。

<div ng-controller="<c:out value="${controllerNameStripped}"/>">
      <cq:include script="template.jsp"/>
</div>

公開モード

公開モード(アプリがコンテンツ同期を使用して書き出された場合など)では、すべてのページが単一ページアプリ(SPA)になります。 (SPAについて学ぶには、Angular チュートリアル、特にhttps://docs.angularjs.org/tutorial/step_07を使用してください)。

SPAには1つのHTML ページ(<html>要素を含むページ)しかありません。 このページは「レイアウトテンプレート」と呼ばれます。 Angularの用語では、「アプリケーションのすべてのビューに共通のテンプレート」です。 このページを「トップレベルのアプリページ」と見なします。 慣例として、トップレベルのアプリページは、ルートに最も近い(リダイレクトではない)アプリケーションのcq:Page ノードです。

アプリの実際のURIは公開モードでは変更されないため、このページからの外部アセットへの参照では相対パスを使用する必要があります。 したがって、書き出す画像をレンダリングする際に、このトップレベルページを考慮した特別な画像コンポーネントが提供されます。

SPAとして、このレイアウトテンプレートページは単にng-view ディレクティブを持つdiv要素を生成します。

 <div ng-view ng-class="transition"></div>

Angular route サービスは、この要素を使用して、現在のページ(template.jspに含まれる)のオーサリング可能なコンテンツを含む、アプリ内のすべてのページのコンテンツを表示します。

body.jsp ファイルには、空のheader.jspとfooter.jspが含まれています。 すべてのページに静的コンテンツを提供する場合は、アプリでこれらのスクリプトを上書きできます。

最後に、サーバーで生成される2つの特殊なJS ファイルを含むjavascript clientlibが<body>要素の下部に含まれます(<page name>.angular-app-module.jsと​<page name>.angular-app-controllers.js)。

angular-app-module.js.jsp angular-app-module-js-jsp

このスクリプトは、アプリケーションのAngular モジュールを定義します。 このスクリプトの出力は、テンプレートのコンポーネントの残りの部分がng-page.jspのhtml要素を介して生成するマークアップにリンクされています。この要素には、次の属性が含まれます。

ng-app="<c:out value='${applicationName}'/>"

この属性は、このDOM エレメントの内容が次のモジュールにリンクされていることをAngularに示します。 このモジュールは、ビュー(AEMではcq:Page リソースになります)を対応するコントローラにリンクします。

このモジュールは、wcmMode変数をスコープに公開し、Content Sync更新ペイロードを取得するURIを設定するAppControllerという名前のトップレベルコントローラーも定義します。

最後に、このモジュールは、それぞれの子孫ページ(それ自体を含む)を反復処理し、各ページのルートフラグメントの内容を(angular-route-fragment.js セレクターと拡張機能を介して)レンダリングします。これには、Angularの$routeProviderの設定エントリとして含まれます。 つまり、$routeProviderは、特定のパスが要求されたときにレンダリングするコンテンツをアプリに指示します。

angular-route-fragment.js.jsp angular-route-fragment-js-jsp

このスクリプトは、次の形式を取る必要があるJavaScript フラグメントを生成します。

.when('/<path>', {
    templateUrl: '<path to template>',
    controller: '<controller name>'
})

このコードは、'/<path>'がtemplateUrlのリソースによって処理され、controllerによってワイヤー接続されることを$routeProvider (angular-app-module.js.jspで定義)に示します(次に説明します)。

必要に応じて、このスクリプトを上書きして、変数を含むより複雑なパスを処理できます。 この例は、AEMと共にインストールされる/apps/geometrixx-outdoors-app/components/angular/ng-template-page/angular-route-fragment.js.jsp スクリプトで確認できます。

// note the :id suffix on the path
.when('<c:out value="${resource.path}"/>/:id', {
    templateUrl: '<c:out value="${relativeResourcePath}"/>.template.html',
    controller: '<c:out value="${controllerNameStripped}"/>'
})

angular-app-controllers.js.jsp angular-app-controllers-js-jsp

Angularでは、コントローラは$スコープ内の変数をワイヤー接続し、それらをビューに公開します。 angular-app-controllers.js.jsp スクリプトは、angular-app-module.js.jspで示すパターンに従います。このパターンでは、それぞれの子孫ページ(それ自体を含む)を反復処理し、各ページで定義されるコントローラーフラグメントを(controller.js.jspを介して)出力します。 定義するモジュールはcqAppControllersと呼ばれ、ページコントローラーを使用できるように、トップレベルのアプリモジュールの依存関係としてリストする必要があります。

controller.js.jsp controller-js-jsp

controller.js.jsp スクリプトは、各ページのコントローラーフラグメントを生成します。 このコントローラーフラグメントは次の形式を取ります。

.controller('<c:out value="${controllerNameStripped}"/>', ['$scope', '$http',
    function($scope, $http) {
        var data = $http.get('<c:out value="${relativeResourcePath}"/>.angular.json' + cacheKiller);

        // component fragments which consume the contents of `data` go here
    }
])

data変数には、Angular $http.get メソッドから返されたpromiseが割り当てられます。 このページに含まれる各コンポーネントは、必要に応じて、(angular.json.jsp スクリプトを介して)一部の.json コンテンツを使用できるようにし、解決時にこのリクエストの内容に基づいて処理を行うことができます。 ファイルシステムにアクセスするだけなので、モバイルデバイスでのリクエストは非常に高速です。

この方法でコンポーネントをコントローラーの一部にするには、/libs/mobileapps/components/angular/ng-component コンポーネントを拡張し、frameworkType: angular プロパティを含める必要があります。

template.jsp template-jsp

body.jsp セクションで最初に導入されたtemplate.jspには、ページのparsysが単純に含まれています。 公開モードでは、このコンテンツは直接参照され(<page-path>.template.html)、$routeProviderで設定されたtemplateUrlを介してSPAに読み込まれます。

このスクリプトのparsysは、任意のタイプのコンポーネントを受け入れるように設定できます。 ただし、(SPAではなく)従来のweb サイト用に構築されたコンポーネントを扱う場合は、注意が必要です。 例えば、基盤画像コンポーネントは、アプリ内のアセットを参照するように設計されていないため、トップレベルのアプリページでのみ正しく機能します。

angular-module-list.js.jsp angular-module-list-js-jsp

このスクリプトは、トップレベルのAngular アプリモジュールのAngular依存関係を単に出力します。 これはangular-app-module.js.jspで参照されています。

header.jsp header-jsp

アプリの上部に静的コンテンツを配置するスクリプト。 このコンテンツは最上位ページに含まれており、ビューの範囲外にあります。

アプリの下部に静的コンテンツを配置するスクリプト。 このコンテンツは最上位ページに含まれており、ビューの範囲外にあります。

js_clientlibs.jsp js-clientlibs-jsp

JavaScript クライアントライブラリを含めるには、このスクリプトを上書きします。

css_clientlibs.jsp css-clientlibs-jsp

CSS クライアントライブラリを含めるには、このスクリプトを上書きします。

アプリコンポーネント app-components

アプリコンポーネントは、AEM インスタンス(パブリッシュまたはオーサー)で動作するだけでなく、アプリケーションコンテンツがContent Syncを介してファイルシステムに書き出される場合にも動作する必要があります。 したがって、コンポーネントには次の特性が含まれている必要があります。

  • PhoneGap アプリケーション内のすべてのアセット、テンプレート、およびスクリプトは、比較的参照する必要があります。
  • AEM インスタンスがオーサーモードまたはパブリッシュモードで動作している場合は、リンクの処理が異なります。

相対Assets relative-assets

PhoneGap アプリケーション内の任意のアセットのURIは、プラットフォームごとに異なるだけでなく、アプリの各インストールで一意です。 例えば、iOS Simulatorで実行中のアプリの次のURIに注意してください。

file:///Users/userId/Library/Application%20Support/iPhone%20Simulator/7.0.3/Applications/24BA22ED-7D06-4330-B7EB-F6FC73251CA3/Library/files/www/content/phonegap/geometrixx/apps/ng-geometrixx-outdoors/en/home.html

パスに「24BA22ED-7D06-4330-B7EB-F6FC73251CA3」というGUIDをメモします。

PhoneGap デベロッパーとして、関係するコンテンツはwww ディレクトリの下にあります。 アプリアセットにアクセスするには、相対パスを使用します。

この問題を複合するために、PhoneGap アプリケーションではシングルページアプリ(SPA)パターンを使用して、ベース URI (ハッシュを除く)が変更されないようにします。 したがって、を参照するすべてのアセット、テンプレート、またはスクリプトは、トップレベルのページに関連している必要があります。 最上位ページでは、*<name>*.angular-app-module.jsおよび*<name>*.angular-app-controllers.jsによってAngular ルーティングとコントローラが初期化されます。 このページは、sling:redirectを拡張しないリポジトリのルートに最も近いページである必要があります。

相対パスを扱うために、いくつかのヘルパーメソッドを使用できます。

  • FrameworkContentExporterUtils.getTopLevelAppResource
  • FrameworkContentExporterUtils.getRelativePathToRootLevel
  • FrameworkContentExporterUtils.getPathToAsset

使用例を確認するには、/libs/mobileapps/components/angularにあるmobileapps ソースを開きます。

すべてのWCM モードをサポートするには、リンクでng-click="go('/path')"関数を使用する必要があります。 この関数は、リンクアクションを正しく決定するためにスコープ変数の値に依存します。

<c:choose><c:when test="${wcmMode}">
    <%-- WCMMode is enabled - page is being rendered in AEM --%>
    $scope.wcmMode = true;
</c:when><c:otherwise>
    <%-- WCMMode is disabled --%>
    $scope.wcmMode = false;
</c:otherwise></c:choose>

$scope.wcmMode == trueの場合、URLのパスやページ部分が変更されるように、通常の方法で各ナビゲーションイベントを処理します。

または、$scope.wcmMode == falseの場合、各ナビゲーションイベントによってURLのハッシュ部分が変更され、Angular ngRoute モジュールによって内部で解決されます。

コンポーネントスクリプトの詳細 component-script-details

chlimage1-36

ng-component.jsp ng-component-jsp

このスクリプトは、編集モードが検出されたときに、コンポーネントの内容または適切なプレースホルダーを表示します。

template.jsp template-jsp-1

template.jsp スクリプトは、コンポーネントのマークアップをレンダリングします。 問題のコンポーネントがAEMから抽出されたJSON データ(「ng-text」: /libs/mobileapps/components/angular/ng-text/template.jspなど)によって駆動される場合、このスクリプトは、ページのコントローラースコープによって公開されたデータでマークアップを接続する責任があります。

ただし、パフォーマンス要件により、クライアント側のテンプレート(データバインディングとも呼ばれます)を実行しないことが指示されることがあります。 この場合、コンポーネントのマークアップをサーバーサイドにレンダリングするだけで、ページテンプレートコンテンツに含まれます。

overhead.jsp overhead-jsp

JSON データによって駆動されるコンポーネント(「ng-text」: /libs/mobileapps/components/angular/ng-textなど)では、overhead.jspを使用してtemplate.jspからすべてのJava コードを削除できます。 その後、template.jspから参照され、リクエストで公開されるすべての変数を使用できます。 この戦略は、プレゼンテーションからロジックを分離することを奨励し、新しいコンポーネントが既存のコンポーネントから派生する場合にコピーおよびペーストする必要があるコードの量を制限します。

controller.js.jsp controller-js-jsp-1

AEM ページテンプレートで説明されているように、各コンポーネントはJavaScript フラグメントを出力して、data プロミスによって公開されたJSON コンテンツを使用できます。 Angularの規則に従って、コントローラはスコープへの変数の割り当てにのみ使用してください。

angular.json.jsp angular-json-jsp

このスクリプトは、ng-pageを拡張するページごとに書き出されるページ全体の’<page-name>.angular.json’ ファイルにフラグメントとして含まれます。 このファイルでは、コンポーネント開発者は、コンポーネントに必要なJSON構造を公開できます。 「ng-text」の例では、この構造は単にコンポーネントのテキストコンテンツと、コンポーネントにリッチテキストが含まれているかどうかを示すフラグを含みます。

Geometrixx outdoors アプリの製品コンポーネントは、より複雑な例です(/apps/geometrixx-outdoors-app/components/angular/ng-product)。

{
    "content-par/ng-product": {
        "items": [{
            "name": "Cajamara",
            "description": "Bike",
            "summaryHTML": "",
            "price": "$610.00",
            "SKU": "eqsmcj",
            "numberOfLikes": "0",
            "numberOfComments": "0"
        }]
    },
    "content-par/ng-product/ng-image": {
        "items": [{
            "hasContent": true,
            "imgSrc": "home/products/eq/eqsm/eqsmcj/jcr_content/content-par/ng-product/ng-image.img.jpg/1377771306985.jpg",
            "description": "",
            "alt": "Cajamara",
            "title": "Cajamara",
            "hasLink": false,
            "linkPath": "",
            "attributes": [{
                "attributeName": "class",
                "attributeValue": "cq-dd-image"
            }]
        }]
    }
}

CLI Assets ダウンロードの内容 contents-of-the-cli-assets-download

Apps コンソールからCLI アセットをダウンロードして特定のプラットフォーム用に最適化し、PhoneGap コマンドライン統合(CLI) APIを使用してアプリを構築します。 ローカルファイルシステムに保存するZIP ファイルの内容には、次の構造があります。

.cordova/
  |- hooks/
     |- after_prepare/
     |- before_platform_add/
     |- Other Hooks
plugins/
www/
  |- config.xml
  |- index.html
  |- res/
  |- etc/
  |- apps/
  |- content/
  |- package.json
  |- package-update.json

.cordova cordova

これは、現在のOS設定によっては表示されない隠しディレクトリです。 含まれているアプリフックを変更する予定がある場合は、このディレクトリが表示されるようにOSを設定する必要があります。

.cordova/hooks/ cordova-hooks

このディレクトリには、CLI フック ​が含まれています。 hook ディレクトリのフォルダーには、ビルド中に正確なポイントで実行されるnode.js スクリプトが含まれています。

.cordova/hooks/after-platform_add/ cordova-hooks-after-platform-add

after-platform_add ディレクトリには、copy_AMS_Conifg.js ファイルが含まれています。 このスクリプトは、Adobe Mobile Services Analyticsのコレクションをサポートするように設定ファイルをコピーします。

.cordova/hooks/after-prepare/ cordova-hooks-after-prepare

after-prepare ディレクトリには、copy_resource_files.js ファイルが含まれています。 このスクリプトは、いくつかのアイコンをコピーし、画面の画像をプラットフォーム固有の場所にスプラッシュします。

.cordova/hooks/before_platform_add/ cordova-hooks-before-platform-add

before_platform_add ディレクトリには、install_plugins.js ファイルが含まれています。 このスクリプトは、Cordova プラグイン識別子のリストを繰り返し実行し、検出したプラグイン識別子がまだ使用できないものをインストールします。

この方法では、Maven content-package:install コマンドが実行されるたびに、プラグインをAEMにバンドルしてインストールする必要はありません。 ファイルをSCM システムにチェックインする別の方法として、繰り返し作業を行う必要があります。

.cordova/hooks/Other Hook cordova-hooks-other-hooks

必要に応じて他のフックを含めます。 次のフックを使用できます(Phonegap サンプル hello world アプリから提供されています)。

  • after_build
  • before_build
  • after_compile
  • before_compile
  • after_docs
  • before_docs
  • after_emulate
  • before_emulate
  • after_platform_add
  • before_platform_add
  • after_platform_ls
  • before_platform_ls
  • after_platform_rm
  • before_platform_rm
  • after_plugin_add
  • before_plugin_add
  • after_plugin_ls
  • before_plugin_ls
  • after_plugin_rm
  • before_plugin_rm
  • after_prepare
  • before_prepare
  • after_run
  • before_run

platforms/ platforms

このディレクトリは、プロジェクトでphonegap run <platform> コマンドを実行するまで空です。 現在、<platform>iosまたはandroidのいずれかです。

特定のプラットフォーム用にアプリを構築すると、対応するディレクトリが作成され、プラットフォーム固有のアプリコードが含まれます。

plugins/ plugins

プラグインディレクトリには、phonegap run <platform> コマンドを実行した後、.cordova/hooks/before_platform_add/install_plugins.js ファイルにリストされている各プラグインが入力されます。 ディレクトリは最初は空です。

www/ www

www ディレクトリには、アプリの外観と動作を実装するすべてのweb コンテンツ(HTML、JS、CSS ファイル)が含まれます。 後述の例外を除き、このコンテンツはAEMから送信され、Content Syncを介して静的フォームに書き出されます。

www/config.xml www-config-xml

PhoneGap ドキュメント (https://docs.phonegap.com)では、このファイルを「グローバル設定ファイル」と呼んでいます。 config.xmlには、アプリの名前、アプリの「環境設定」(例えば、iOSのweb ビューでオーバースクロールが許可されているかどうかなど)、PhoneGap ビルドで使用される​ のみ ​のプラグイン依存関係など、多くのアプリプロパティが含まれています。

config.xml ファイルは、AEMの静的ファイルであり、Content Syncを介してそのまま書き出されます。

www/index.html www-index-html

index.html ファイルは、アプリの開始ページにリダイレクトされます。

config.xml ファイルには、content要素が含まれています。

<content src="content/phonegap/geometrixx/apps/ng-geometrixx-outdoors/en.html" />

PhoneGap ドキュメント (https://docs.phonegap.com)では、この要素は「オプションの<content>要素は、トップレベルのweb アセットディレクトリ内のアプリの開始ページを定義します。 デフォルト値はindex.htmlで、通常はプロジェクトの最上位のwww ディレクトリに表示されます。」

index.html ファイルが存在しない場合、PhoneGap ビルドは失敗します。 したがって、このファイルが含まれています。

www/res www-res

res ディレクトリには、スプラッシュ画面の画像とアイコンが含まれています。 copy_resource_files.js スクリプトは、after_prepareのビルド フェーズ中に、ファイルをプラットフォーム固有の場所にコピーします。

www/etc www-etc

AEMでは、/etc ノードに静的なclientlib コンテンツが含まれています。 etc ディレクトリには、Topcoat、AngularJSおよびGeometrixx ng-clientlibsall ライブラリが含まれます。

ww/apps www-apps

apps ディレクトリには、スプラッシュページに関連するコードが含まれています。 AEM アプリのスプラッシュページのユニークな特徴は、ユーザーの操作なしでアプリを初期化することです。 したがって、アプリのclientlib コンテンツ(CSSとJSの両方)は、パフォーマンスを最大化するために最小限に抑えられています。

www/content www-content

コンテンツディレクトリには、アプリのweb コンテンツの残りの部分が含まれます。 コンテンツには、次のファイルを含めることができますが、これらに限定されません。

  • AEMで直接作成されるHTMLのページコンテンツ
  • AEM コンポーネントに関連付けられた画像アセット
  • サーバーサイドスクリプトによって生成されるJavaScript コンテンツ
  • ページまたはコンポーネントコンテンツを記述するJSON ファイル

www/package.json www-package-json

package.json ファイルは、full コンテンツ同期のダウンロードに含まれるファイルをリストするマニフェストファイルです。 このファイルには、コンテンツ同期ペイロードが生成されたタイムスタンプも含まれています(lastModified)。 このプロパティは、AEMからアプリの部分的な更新をリクエストする場合に使用されます。

www/package-update.json www-package-update-json

このペイロードがアプリ全体のダウンロードである場合、このマニフェストにはファイルの正確なリストがpackage.jsonとして含まれます。

ただし、このペイロードが部分的な更新である場合、package-update.jsonには、この特定のペイロードに含まれるファイルのみが含まれます。

recommendation-more-help
experience-manager-65-help-mobile