CMS コネクタページコード
CMS Connect を使用してパーソナライズされたコンテンツをエクスペリエンスビルダーサイトで表示する場合は、設定プロセスで下記のコネクタ JSP ページコードを使用する必要があります。
Adobe Experience Manager のパーソナライズされたコンテンツをサイトに適用するには、下記のコードを含む JSP コネクタページを作成します。このコードは、必要に応じて拡張できます。サイトでパーソナライズを設定するための完全な手順は、「CMS コンテンツのパーソナライズ」を参照してください。
コネクタ JSP ページロジックには次のセクションがあります。
- 要求パラメータ。要求パラメータ (ペイロード) には、サイトからコネクタページに渡されるデータが含まれます。データには、componentUrls (パーソナライズを実行する必要のあるコンポーネントパス URL の配列)、asset (JSP ページの読み込み時に挿入される CMS 接続の Asset Path 項目で指定されている JavaScript アセット)、clientContext (IP アドレス、言語、国、都道府県、市区郡、緯度、経度)、requestId (応答の信頼性を検証するために postMessage の一部として返されるトークン)、ドメイン (パーソナライズされたコンテンツを要求しているサイトのドメイン) が含まれます。
- パーソナライズ JSP ロジック。下記の基本ロジックを提供しています。このロジックは、必要に応じて拡張できます。
- JavaScript。JSP には、サイトに postMessage を送信するための Salesforce 提供の JavaScript を含めます。スクリプトの src は、<your_site_domain/_sfdc/cms-connect/aem_personalization/salesforceConnector.js> のように構成します。CMS 接続の [アセットパス] 項目で指定されているすべてのアセットが JSP に含まれます。
- 応答。最後のセクションは、応答オブジェクトから構成され、postMessage を送信します。送信処理は、前のセクションでインクルードした JavaScript が行います。
1<!-- Salesforce connector to run AEM personalization-->
2<%@include file="/libs/foundation/global.jsp"%><%
3%><%@page import="
4 java.io.StringWriter,
5 java.net.URL,
6 com.day.cq.wcm.api.WCMMode,
7 com.day.cq.wcm.core.stats.PageViewStatistics,
8 com.day.text.Text,
9 java.util.ResourceBundle,
10 com.day.cq.i18n.I18n,
11 com.day.cq.personalization.TargetedContentManager,
12 com.day.cq.personalization.ClientContextUtil,
13 org.apache.sling.commons.json.JSONObject,
14 org.apache.sling.commons.json.JSONArray,
15 com.day.cq.commons.JS,
16 org.apache.sling.engine.*,
17 org.apache.sling.api.SlingHttpServletRequest,
18 org.apache.sling.api.resource.ResourceResolver,
19 java.util.*,
20 com.day.cq.*" %><%
21
22 %><cq:includeClientLib categories="personalization.kernel"/><%
23 if(request.getParameter("payload") != null) {
24 // For every component URL, get the Teasers object and strategy.
25 JSONObject payload = new JSONObject(request.getParameter("payload"));
26 JSONArray compUrls = payload.getJSONArray("componentUrls");
27 String asset = payload.getString("asset");
28 HashMap<String, JSONArray> teaserMap = new HashMap<>();
29 HashMap<String, String> strategyMap = new HashMap<>();
30 ResourceBundle resourceBundle = slingRequest.getResourceBundle(null);
31 I18n i18n = new I18n(resourceBundle);
32 final TargetedContentManager targetedContentManager = sling.getService(TargetedContentManager.class);
33 SlingRequestProcessor requestProcessor = sling.getService(SlingRequestProcessor.class);
34 ResourceResolver resolver = slingRequest.getResourceResolver();
35 for(int j=0; j<compUrls.length(); j++) {
36
37 JSONArray allTeasers = new JSONArray();
38 String strategy = "";
39
40 try {
41 String requestPath = new URL(compUrls.getString(j)).getPath().replaceAll(".html", "");
42
43 Resource resourceObject = resolver.getResource(requestPath);
44
45 Node rootNode = resourceObject.adaptTo(Node.class);
46 ValueMap prop = resourceObject.adaptTo(ValueMap.class);
47
48 // Get the strategy path
49 String strategyPath = prop.get("strategyPath", (String) null);
50 if (strategyPath != null) {
51 strategy = Text.getName(strategyPath);
52 strategy = strategy.replaceAll(".js", "");
53 }
54
55 // Get the campaign path
56 String campaignPath = prop.get("campaignpath", (String) null);
57 String campaignClass = "";
58 if (campaignPath != null) {
59 Page campaignPage = pageManager.getPage(campaignPath);
60 if (campaignPage != null) {
61 campaignClass = "campaign-" + campaignPage.getName();
62 }
63 }
64
65 JSONObject teaserInfo = targetedContentManager.getTeaserInfo(resourceResolver, campaignPath, requestPath);
66 allTeasers = teaserInfo.getJSONArray("allTeasers");
67
68 // Add selectors from the current page for the mobile case, e.g. "smart", "feature" etc.
69 String selectors = slingRequest.getRequestPathInfo().getSelectorString();
70 selectors = selectors != null ? "." + selectors : "";
71
72 for (int i = 0; i < allTeasers.length(); i++) {
73 JSONObject t = (JSONObject) allTeasers.get(i);
74 t.put("url", t.get("path") + "/_jcr_content/par" + selectors + ".html");
75 }
76
77 // Use "default" child node as default teaser and add at the end of the teaser list
78 JSONObject defaultTeaser = new JSONObject();
79 defaultTeaser.put("path", resourceObject.getPath() + "/default");
80 defaultTeaser.put("url", resourceObject.getPath()+ ".default" + selectors + ".html");
81 defaultTeaser.put("name", "default");
82 defaultTeaser.put("title", i18n.get("Default"));
83 defaultTeaser.put("campainName", "");
84 defaultTeaser.put("thumbnail", resourceObject.getPath() + ".thumb.png");
85 allTeasers.put(defaultTeaser);
86 } catch (Exception e) {
87 // If an exception occurs for any of the component URLs, we will put default values in teaserMap and strategyMap
88 }
89
90 teaserMap.put(compUrls.getString(j), allTeasers);
91 strategyMap.put(compUrls.getString(j), strategy);
92
93 }
94
95 String requestId = payload.getString("requestId");
96 String domain = payload.getString("domain");
97 JSONObject teaserJson = new JSONObject(teaserMap);
98 JSONObject strategyJson = new JSONObject(strategyMap);
99
100 %>
101
102 <html>
103 <head>
104 <script type="text/javascript" src="/etc/clientlibs/granite/jquery.js"></script>
105 <script type="text/javascript" src="/etc/clientlibs/granite/utils.js"></script>
106 <script type="text/javascript" src="/etc/clientlibs/granite/jquery/granite.js"></script>
107 <script type="text/javascript" src="/etc/clientlibs/foundation/jquery.js"></script>
108 <script type="text/javascript" src="/etc/clientlibs/foundation/shared.js"></script>
109 <script type="text/javascript" src="/etc/clientlibs/granite/lodash/modern.js"></script>
110 <script type="text/javascript" src="/etc/clientlibs/foundation/personalization/kernel.js"></script>
111 <!--TODO: Include the script that will send a postMessage to your site. The path of the JS is <your site domain/_sfdc/cms-connect/aem_personalization/salesforceConnector.js> -->
112 <!--The below line injects a script that is passed in the request -->
113 <script type="text/javascript" src="<%= asset %>"></script>
114 </head>
115
116 <body>
117 <script>
118 var teaserMap = <%= teaserJson %>;
119 var strategyMap = <%= strategyJson %>;
120 var requestId = "<%= requestId %>";
121 var domain = "<%= domain %>";
122 setClientContext();
123 var resolvedTeasers = getResolvedTeasers(teaserMap, strategyMap);
124 CMS_CONNECT_PERSONALIZATION_AEM.responsePersonalization(resolvedTeasers, requestId, domain);
125
126
127 // This is a sample client-context that can be used.
128 // Salesforce provides the client-context object which can be used to build the json
129 /**
130 * @typedef {object} payload.clientContext
131 * @property {String} ipAddress User's ipAddress
132 * @property {String} language User language
133 * @property {String} country User's country
134 * @property {String} state User's state
135 * @property {String} city User's city
136 * @property {String} latitude User's latitude
137 * @property {String} longitude User's longitude
138 */
139 function setClientContext() {
140 var payload = <%= payload %>;
141 var clientContext = payload.clientContext;
142 // Set client-context
143 var clientContextJson = {};
144 clientContextJson.surferinfo = {
145 'IP': clientContext.ipAddress
146 };
147 clientContextJson.profile = {
148 'language': clientContext.language,
149 'country': clientContext.country,
150 'state': clientContext.state,
151 'city': clientContext.city
152 };
153 clientContextJson.geolocation = {
154 'latitude': clientContext.latitude,
155 'longitude': clientContext.longitude
156 };
157 CQ_Analytics.ClientContextMgr.clientcontext = clientContextJson;
158 }
159
160 /**
161 * Runs personalization logic for all the component URLs requested
162 * @param {teaserMap} Map of componentUrl as key and teasers object for the component
163 * @param {strategyMap} Map of componentUrl as key and strategy for the component
164 */
165 function getResolvedTeasers(teaserMap, strategyMap) {
166 var resolvedTeasers = {};
167 for (var key in teaserMap) {
168 try {
169 if (teaserMap.hasOwnProperty(key)) {
170 var resolvedTeaser = CQ_Analytics.Engine.resolveTeaser(teaserMap[key], strategyMap[key], null);
171 resolvedTeasers[key] = resolvedTeaser.url.substring(1);
172 }
173 } catch (err) {
174 // If any error occurs in calculating resolved teaser for a component url, we save it as error
175 resolvedTeasers[key] = "error";
176 }
177 }
178
179 return resolvedTeasers;
180 }
181 </script>
182 </body>
183 </html>
184 <%
185 }
186 %>