Adobe Analytics使用s.pageName
属性来唯一标识页面并关联为页面收集的数据。 通常,您在AEM中执行以下任务,为AEM发送到Analytics的此属性分配值:
使用Analytics云服务框架将CQ变量映射到Analytics s.pageName
属性。 (请参阅使用Adobe Analytics属性映射组件数据。)
设计页面组件,使其包含您映射到s.pageName
属性的CQ变量。 (请参阅为自定义组件实施Adobe Analytics跟踪。)
要在站点控制台和内容分析中显示Analytics报告数据,AEM要求每个页面的s.pageName
属性值。 AEM Analytics Java API定义您实施的AnalyticsPageNameProvider
接口,以向站点控制台和内容分析提供s.pageName
属性的值。 您的AnaltyicsPageNameProvider
服务会为报告目的解析服务器上的pageName属性,因为可以使用客户端上的Javascript动态设置该属性以用于跟踪目的。
DefaultPageNameProvider
服务是默认服务,它确定用于检索页面的Analytics数据的s.pageName
属性的值。 该服务与AEM基础页面组件(/libs/foundation/components/page
)配合使用。 此页组件定义要映射到s.pageName
属性的以下CQ变量:
pagedata.path
:该值设置为页面路径。pagedata.title
:该值设置为页面标题。pagedata.navTitle
:该值设置为页面导航标题。DefaultPageNameProvider
服务确定这些CQ变量中的哪个映射到Analytics云服务框架中的s.pageName
属性。 然后,该服务确定用于检索分析报告数据的相应页面属性:
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
的页面使用值content:geometrixx:en
表示s.pageName
。
DefaultPageNameProvider服务使用100的服务等级。
为页面维护分析数据的完整历史记录要求用于页面的s.pageName属性的值始终不变。 但是,可以轻松更改基础页面组件定义的分析属性。 例如,移动页面会更改pagedata.path
的值,并中断报告历史记录的连续性:
为确保报告连续性,s.pageName
的值应具有以下特征:
例如,自定义页面组件可以包含一个页面属性,作者使用该属性为用作s.pageProperties
属性值的页面指定唯一ID:
s.pageProperties
属性。请咨询Analytics顾问,帮助您制定s.pageName
价值的有效战略。
将com.day.cq.analytics.sitecatalyst.AnalyticsPageNameProvider
接口作为OSGi服务实现,以自定义检索s.pageName
属性值的逻辑。 站点页面分析和内容分析使用服务从Analytics检索报告数据。
AnalyticsPageNameProvider接口定义了必须实现的两种方法:
getPageName
:返回 String
表示用作属性的值的 s.pageName
值。
getResource
:返回 org.apache.sling.api.resource.Resource
表示与属性关联的页面的对 s.pageName
象。
这两种方法都以com.day.cq.analytics.sitecatalyst.AnalyticsPageNameContext
对象作为参数。 AnalyticsPageNameContext
类提供有关分析调用的上下文的信息:
Framework
对象。Resource
对象。ResourceResolver
对象。类还为页面名称提供setter。
以下示例AnalyticsPageNameProvider
实现支持自定义页面组件:
s.pageName
属性值的字段。jcr:content
节点的pageName属性中。s.pageName
属性的分析属性称为pagedata.pagename
。 此属性将映射到Analytics框架中的s.pageName
属性。如果正确配置了框架映射,则getPageName
方法的以下实现将返回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;
}
getResource方法的以下实现为页面返回Resource对象:
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 + "\"";
}
以下代码代表整个类,包括配置服务的SCR注释。 请注意,服务等级为200,它将覆盖默认服务。
/*************************************************************************
*
* ADOBE CONFIDENTIAL
* __________________
*
* Copyright 2019 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;
import java.util.Iterator;
import javax.jcr.query.Query;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.osgi.framework.Constants;
import org.osgi.service.component.annotations.Component;
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.analytics.sitecatalyst.AnalyticsPageNameContext.S_PAGE_NAME;
/**
* Default implementation of {@link AnalyticsPageNameProvider} that resolves
* page title, path or navTitle if mapped in {@link Framework}.
*/
@Component(
service = { AnalyticsPageNameProvider.class },
property = {
Constants.SERVICE_DESCRIPTION + "=Example Page Name Resolver implementation",
Constants.SERVICE_RANKING + ":Integer=200"
}
)
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 + "\"";
}
}