Adobe Analytics は、s.pageName プロパティを使用してページを一意に識別し、そのページのために収集されたデータを関連付けます。AEM から Analytics に送信されるこのプロパティに値を割り当てるには、通常は AEM 内で次のタスクを実行します。
- Analytics クラウドサービスフレームワークを使用して、CQ 変数を Analytics の s.pageName プロパティにマップする(コンポーネントデータと SiteCatalyst プロパティのマッピングを参照)。
- ページコンポーネントを、s.pageName プロパティにマップする CQ 変数を含むようにデザインする(カスタムコンポーネント用の SiteCatalyst 追跡機能の実装を参照)。
Analytics レポートデータをサイトコンソールとコンテンツインサイトに公開するには、各ページの s.pageName プロパティの値が必要です。サイトコンソールとコンテンツインサイトに s.pageName プロパティの値を提供するには、AEM Analytics の Java API で定義されている AnalyticsPageNameProvider インターフェイスを実装します。AnaltyicsPageNameProvider サービスは、レポート生成のためにサーバー上の pageName プロパティを解決します。このプロパティは、追跡のためにクライアント上で Javascript を使用して動的に設定できるからです。
DefaultPageNameProvider サービスは、Analytics 統合機能パックによってインストールされます。これは、ページの Analytics データを取得するために使用される s.pageName プロパティの値を決定するデフォルトのサービスです。このサービスは、AEM の基盤ページコンポーネント(/libs/foundation/components/page)と連携して動作します。このページコンポーネントは、s.pageName プロパティにマップされる次の CQ 変数を定義します。
- pagedata.path:ページのパスに設定されます。
- pagedata.title:ページのタイトルに設定されます。
- pagedata.navTitle:ページのナビゲーションのタイトルに設定されます。
DefaultPageNameProvider サービスは、Analytics クラウドサービスフレームワークの s.pageName プロパティにマップされる CQ 変数を決定します。その後、Analytics レポートデータの取得に使用する適切なページプロパティを決定します。
- pagedata.path:このサービスは page.getPath() を使用します。
- pagedata.title:このサービスは page.getTitle() を使用します。
- pagedata.navTitle:このサービスは page.getNavigationTitle() を使用します。
page オブジェクトは、そのページの com.day.cq.wcm.api.Page Java オブジェクトです。
CQ 変数をフレームワークの s.pageName プロパティにマップしない場合、s.pageName の値はページのパスから生成されます。例えば、/content/geometrixx/en というパスを持つページでは、s.pageName の値は content:geometrixx:en となります。
注意:
DefaultPageNameProvider サービスは、サービスランキングとして 100 を使用します。
ページの分析データに関するすべての履歴を維持するには、一度も変更されたことがないページに使用される s.pageName プロパティの値が必要です。ただし、基盤ページコンポーネントが定義する分析プロパティは簡単に変更できます。例えば、ページを移動すると pagedata.path の値が変更され、レポート履歴の連続性が途切れて、次のようなことが起こります。
- 前のパスで収集されたデータは、このページと関連付けられなくなります。
- 以前に他のページが使用していたパスを別のページが使用する場合は、後から使用するほうのページがそのパスのデータを継承します。
レポートの連続性を保証するには、s.pageName の値に以下の性質を持たせる必要があります。
- 一意性。
- 安定性。
- 人間にとっての可読性。
- ページに含まれる Analytics 変数は、ページプロパティに保存されている一意の ID の値に設定されます。
- Analytics 変数は、Analytics フレームワークの s.pageProperties プロパティにマップされます。
- AnalytcsPageNameProvider インターフェイスの実装は、このページプロパティの値を取得して、ページの Analytics データのクエリーに使用します。
注意:
s.pageName の値について効果的な戦略を策定できるよう、Analytics のコンサルタントに相談してください。
com.day.cq.analytics.sitecatalyst.AnalyticsPageNameProvider インターフェイスを OSGi サービスとして実装し、s.pageName プロパティの値を取得するロジックをカスタマイズします。サイトページ分析およびコンテンツインサイトでこのサービスを使用して、Analytics からレポートデータを取得します。
AnalyticsPageNameProvider インターフェイスで定義されている次の 2 つのメソッドを実装する必要があります。
- getPageName:s.pageName プロパティとして使用する値を表す String 値を返します。
- getResource:s.pageName プロパティに関連付けられたページを表す org.apache.sling.api.resource.Resource オブジェクトを返します。
- ページリソースのベースパス。
- Analytics クラウドサービス設定の Framework オブジェクト。
- ページの Resource オブジェクト。
- ページの ResourceResolver オブジェクト。
以下に示すサンプル AnalyticsPageNameProvider 実装は、以下のようなカスタムページコンポーネントをサポートしています。
- 基盤ページコンポーネントを拡張したコンポーネントです。
- ダイアログには、作成者が s.pageName プロパティの値を指定するためのフィールドが含まれます。
- プロパティの値は、ページインスタンスの jcr:content ノードの pageName プロパティに保存されます。
- s.pageName プロパティを保存する Analytics プロパティは、pagedata.pagename です。このプロパティは、Analytics フレームワークの s.pageName プロパティにマップされます。
public String getPageName(AnalyticsPageNameContext context) { String pageName = null; Framework framework = context.getFramework(); Resource resource = context.getResource(); if (resource != null && framework != null && framework.mapsSCVariable(S_PAGE_NAME)) { String cqVar = framework.getMapping(S_PAGE_NAME); Page page = resource.adaptTo(Page.class); if (cqVar.equals("pagedata.pagename")) { pageName = page.getProperties().get("pageName",null); } } return pageName; }
public Resource getResource(AnalyticsPageNameContext context) { Resource res = null; Framework framework = context.getFramework(); ResourceResolver resolver = context.getResourceResolver(); String pageName = context.getPageName(); String basePath = context.getBasePath(); if (pageName != null && basePath != null && resolver != null && framework != null && framework.mapsSCVariable(S_PAGE_NAME)) { String cqVar = framework.getMapping(S_PAGE_NAME); if (cqVar.equals("pagedata.pagename")) { Iterator<Resource> hits = resolver.findResources(createQuery(pageName, basePath, "pagename"), Query.JCR_SQL2); if (hits.hasNext()) { res = hits.next(); res = res.getParent(); } } } return res; } private String createQuery(String pageName, String basePath, String propName) { return "SELECT * FROM [cq:PageContent] WHERE ISDESCENDANTNODE([" + basePath + "]) and [" + propName + "] = \"" + pageName + "\""; }
/************************************************************************* * * ADOBE CONFIDENTIAL * __________________ * * Copyright 2014 Adobe Systems Incorporated * All Rights Reserved. * * NOTICE: All information contained herein is, and remains * the property of Adobe Systems Incorporated and its suppliers, * if any. The intellectual and technical concepts contained * herein are proprietary to Adobe Systems Incorporated and its * suppliers and may be covered by U.S. and Foreign Patents, * patents in process, and are protected by trade secret or copyright law. * Dissemination of this information or reproduction of this material * is strictly forbidden unless prior written permission is obtained * from Adobe Systems Incorporated. **************************************************************************/ package com.day.cq.analytics.sitecatalyst.impl; import java.util.Iterator; import javax.jcr.query.Query; import org.apache.felix.scr.annotations.Component; import org.apache.felix.scr.annotations.Properties; import org.apache.felix.scr.annotations.Property; import org.apache.felix.scr.annotations.Service; import org.apache.sling.api.resource.Resource; import org.apache.sling.api.resource.ResourceResolver; import org.osgi.framework.Constants; import com.day.cq.analytics.sitecatalyst.AnalyticsPageNameContext; import com.day.cq.analytics.sitecatalyst.AnalyticsPageNameProvider; import com.day.cq.analytics.sitecatalyst.Framework; import com.day.cq.wcm.api.Page; import static com.day.cq.wcm.api.NameConstants.PN_TITLE; import static com.day.cq.wcm.api.NameConstants.PN_NAV_TITLE; import static com.day.cq.analytics.sitecatalyst.AnalyticsPageNameContext.S_PAGE_NAME; /** * Default implementation of {@link AnalyticsPageNameProvider} that resolves * page title, path or navTitle if mapped in {@link Framework}. */ @Service @Component(metatype = false) @Properties({ @Property(name = Constants.SERVICE_DESCRIPTION, value = "Example Page Name Resolver implementation"), @Property(name = Constants.SERVICE_RANKING, intValue = 200, propertyPrivate = false) }) public class ExamplePageNameProvider implements AnalyticsPageNameProvider { public String getPageName(AnalyticsPageNameContext context) { String pageName = null; Framework framework = context.getFramework(); Resource resource = context.getResource(); if (resource != null && framework != null && framework.mapsSCVariable(S_PAGE_NAME)) { String cqVar = framework.getMapping(S_PAGE_NAME); Page page = resource.adaptTo(Page.class); if (cqVar.equals("pagedata.path")) { pageName = page.getProperties().get("pageName",null); } } return pageName; } public Resource getResource(AnalyticsPageNameContext context) { Resource res = null; Framework framework = context.getFramework(); ResourceResolver resolver = context.getResourceResolver(); String pageName = context.getPageName(); String basePath = context.getBasePath(); if (pageName != null && basePath != null && resolver != null && framework != null && framework.mapsSCVariable(S_PAGE_NAME)) { String cqVar = framework.getMapping(S_PAGE_NAME); if (cqVar.equals("pagedata.pagename")) { Iterator<Resource> hits = resolver.findResources(createQuery(pageName, basePath, "pagename"), Query.JCR_SQL2); if (hits.hasNext()) { res = hits.next(); res = res.getParent(); } } } return res; } private String createQuery(String pageName, String basePath, String propName) { return "SELECT * FROM [cq:PageContent] WHERE ISDESCENDANTNODE([" + basePath + "]) and [" + propName + "] = \"" + pageName + "\""; } }