Customization of the
Client Context:
Customized client context is used to re use the personalization according to our requirements. Usually people extend the 'Generic store property' to customize the personalization.
Once the customization is done the new folder structure will look as shown below in crx-de. Here 'my user store' is customized client context.
The Apps>projects
folder
Here we will be personnalizing content based on information
retrieved from an external CRM system.
Steps to personalise with external CRM:
Session Store
object: We need to retrieve and keep the data from external application to make it available for our extended client context and is done by method Session
Store object. This is a JavaScript object created on the client side. It uses a
back-end part to retrieve data from the CRM system which can be a servlet. This
is done both on the author and publish instances.
Context Store
component: This is the way we display data in the Client Context.
1) Session Store Creation:
The Session Store is a javascript object library available
both on the author and publish instances. We dont use client context in publish so
, we create two javascript libraries with the following categories(The kernel
is used on both author and publish instances but the ui only on the author
instance.)
kernel - > personalization.stores.kernel
ui - > personalization.stores.ui
Add below code in myuserstore.JS under kernel
// Create the session store called "myuserstore"
if (!CQ_Analytics.CustomStoreMgr ) {
// Create the
session store as a JSONStore
CQ_Analytics.CustomStoreMgr
= CQ_Analytics.JSONStore.registerNewInstance("myuserstore");
CQ_Analytics.CustomStoreMgr.currentId = "";
// Function to
load the data for the current user
CQ_Analytics.CustomStoreMgr.loadData = function() {
var
authorizableId =
CQ_Analytics.ProfileDataMgr.getProperty("authorizableId");
//invoke
your servlet using below code
var url =
"/apps/myuserstore/components/loader.json";
if (
(authorizableId !== CQ_Analytics.CustomStoreMgr.currentId) &
CQ_Analytics.CustomStoreMgr.initialized ) {
console.info("Loading CustomStoreMgr data");
url =
CQ_Analytics.Utils.addParameter(url, "authorizableId",
authorizableId);
try {
var
object = CQ.shared.HTTP.eval(url);
if
(object) { this.data = object; }
}
catch(error) {
console.log("Error", error);
}
CQ_Analytics.CustomStoreMgr.currentId = authorizableId;
}
};
CQ_Analytics.CCM.addListener("configloaded",
function() {
CQ_Analytics.ProfileDataMgr.addListener("update", function() {
this.loadData();
this.fireEvent("update");
},
CQ_Analytics.CustomStoreMgr);
},
CQ_Analytics.CustomStoreMgr);
CQ_Analytics.CustomStoreMgr.addListener("initialize",
function() {
this.loadData();
});
CQ_Analytics.CustomStoreMgr.initialized = false;
}
Now create a java servlet which is used to generate a JSON file during run time, which gets
invoked from url /apps/myuserstore/components/
And below code should create a JSON and place it
in/bin/project/updateclientcontext.json
public class UpdateClientContextClass extends
SlingSafeMethodsServlet {
private static class JSONWriter {
//use tidy kind of JSON creato if required
response.setContentType("application/json;
charset=UTF-8");
response.getWriter().write(writer.toString());
}
}
Note: in above case
we can use some webservice/DB as an external url and iterate its data to
populate the JSON for specific user.
2) Context Store
component Creation: Create a new CQ component in
/apps/myuserstore/components called myuserstore with the properties :
sling:resourceSuperType =
cq/personalization/components/contextstores/genericstoreproperties
componentGroup =
Client Context
Add below code in myuserstore.js in the ui library
if (CQ_Analytics.CustomStoreMgr ) {
// HTML template
CQ_Analytics.CustomStoreMgr.template =
"<input class='customstore-input' type='checkbox'
id='customstore-input-%key%' name='%key%' value='%key%' %checked%>" +
"<label for='customstore-input-%key%'
class='%checkedClass%'>" +
"<div
class='toggle'><div class='green'></div><div
class='red'></div></div>" +
"%label%</label>";
CQ_Analytics.CustomStoreMgr.templateRenderer = function(key, label,
value) {
var
checkedString = ""; var checkedClass = "";
if (value==="true")
{
checkedString = "checked='checked'";
checkedClass =
"checked";
}
var template
= CQ_Analytics.CustomStoreMgr.template;
return
template.replace(/%label%/g, label)
.replace(/%key%/g, key)
.replace(/%checked%/g, checkedString)
.replace(/%checkedClass%/g, checkedClass);
}
CQ_Analytics.CustomStoreMgr.renderer = function(store, divId) {
// first load
data
//
CQ_Analytics.CustomStoreMgr.loadData();
$CQ("#" + divId).children().remove();
var name =
CQ_Analytics.ProfileDataMgr.getProperty("formattedName");
var
templateRenderer = CQ_Analytics.CustomStoreMgr.templateRenderer;
// Set title
$CQ("#" + divId).addClass("cq-cc-customstore");
var div =
$CQ("<div>").html(name + " services");
$CQ("#" + divId).append(div);
var data =
this.getJSON();
if (data) {
for (var i
in data) {
if
(typeof data[i] === 'object') {
$CQ("#" +
divId).append(templateRenderer(data[i].key,data[i].label,data[i].value));
}
}
}
}
CQ_Analytics.CustomStoreMgr.setTraitValue = function(trait, newValue) {
var data =
CQ_Analytics.CustomStoreMgr.data;
if (data) {
data[trait
+ '/value'] = newValue;
}
};
}
Now when the user
reloads the page, the client context with corresponding data will be populated
Here the kernel ui java script invokes our servlet using the servlet url to create the json file. This created JSON data will be getting populated to the client context. Client context will have its own .css files which can be created referring any of the Geometrix .css personalized items.
Use Cases: This customized application can be used to check user data once user logs in, and a personalized teaser can be displayed to relevant users.
External References:
Sitecatalyst integration for
personalization: