Friday 29 August 2014

Customize the client context for cq personalization

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.

-------Similar Posts---------------
Mapping of requests in AEM
Interact With AEM
Run Modes
AEM
Apache Sling in AEM
-------------------------------------

External References:


Sitecatalyst integration for personalization:




Create personalization components in AEM CQ

Personalization: Personalization is a technique to serve personalized content to each user. It can be based on user logged in by city, country
Here are the steps involved in implementing personalization.

Step1: Create the Segments.(Segments hold the rule to be checked while displaying a teaser on any page)

Go to Tootls > Segmentation

                                  


Double click on created segment and configure the test condition to be evaluated. For eg: We are going to display the teaser for ‘Male’ users.

For this, drag the ‘User properties’ from side kick.

                      



Edit the property to check the condition ‘gender=male’
                      


Now the segment will look as below.

                  



Step2:  Create Brand, Campaign Container (Brand holds campaigns, campaign holds teasers)


Once segment is created, Go to > Campaigns (http://localhost:4505/mcmadmin#/content/campaigns)

Create Brand selecting brand template,

           
          

Now create Campaigns by selecting campaign template

                 
   


Step3:  Create Teasers


Once campaign is created, go to lists view and create teasers.

                   

Add some text and image to teaser by editing it. Sample is shown below.


Configure the touch point properties of teaser by selecting the segment in ‘Advanced section’as shown below.
This is the linking point between segment and teaser.

               


Now the campaign page looks as below.



Step4:  Add Teasers to any page
Now go to the page where you want to display the teaser, drag and drop teaser
                      



Enter the configuration selecting campaign to be run for the page as shown below.

                  




Step5:  Test the teaser by setting client context. (Client Context is used to check/modify any user attributes during testing the personalization)



Now go to client context (CTRl+Alt+C) and select a ‘male’ user. You can see the teaser is displayed as shown below.
                 



-------Similar Posts---------------
Mapping of requests in AEM
Interact With AEM
Run Modes
AEM
Apache Sling in AEM
-------------------------------------

Tuesday 10 June 2014

Replication agents & DAM


Replication agents:
-----------------------------
They help to publish the content. Replication agents are mapped to publication. So when we need more than one publish environment, we need replication agents for each one.
Access replication agents through Tools>Replication


Publish flow:

Once site is developed it should be activated by going website> activate
It send alert to replication agent, the request will be put in a queue will be formed for it.
We can restrict continuous attempts of publish through Agents>Setting>Extended> connect time out.
Settings
On modification - helps to publish a page immediately after modification
Activating (publishing) more pages together in AEM/Adobe cq
Access replication tree using below url.
http://localhost:4505/etc/replication/treeactivation.html
Now activate more pages by selecting pages or entire directory.
How to publish a Component immediate after creation or modification?
Push component to publish through Crxde lite by selecting component, then go to replication tab, click on replicate. This will send component immediately to publish.



We have manual way of publishing through build bundle-> install to publish environment. Easier solution to publish content is,we can use direct replicate for the package. For this ensure you configured replication agents.




DAM:
----------
Thumbnails are created automatically in DAM because it is defined default by Adobe in workflow:
http://localhost:4505/cf#/etc/workflow/models/dam/update_asset.html : step> Thumbnail creation
Use sidekick > DAM workflow to create dam related workflows.
All items we uploaded can be seen in CRXDE through http://localhost:4505/crx/de/index.jsp#/content/dam
References section gives the list of all references from pages for an image. Double click on image and see right top (renditions,versions,references)
Securities:
Change admin or author passwords:
------------------
1)
http://localhost:4505/crx/explorer/index.jsp > 'Content explorer' opens below url
http://localhost:4505/crx/explorer/browser/index.jsp
now
Security > change password.
2)
http://localhost:4505/crx/explorer/index.jsp > 'User Administration' opens below url
http://localhost:4505/crx/explorer/ui/usereditor.jsp?ck=1402297401235&Path=/home/users
Select a>admin>change password
Create or delete users canbe done through http://localhost:4505/useradmin.
All users’ preferences can be done through above url.

OSGi component Vs CQ component:
OSGI-Backend part- business component;
CQ-front end part
OSGI bundle can have many no of osgi components and each component can have many services.

-------Similar Posts---------------
Mapping of requests in AEM
Interact With AEM
Run Modes
AEM
Apache Sling in AEM

-------------------------------------

Debug mode:
In start.bat > CQ_JVM_OPTS parameters : add>
-agentlib:jdwp=transport=dt_socket,server=y,address=30303.suspend=n
Read More:
http://helpx.adobe.com/experience-manager/kb/CQ5HowToSetupRemoteDebuggingWithEclipse.html

AEM/ Adobe CQ: Version controlling



AEM/ Adobe CQ: Version controlling

CQ uses svn by default.
Filevault ( VLT)is used when we need crx file system to be available in local system(like accessing code using eclipse).
Create back up of crx code using file vault
To set up the filevault, we need to unzip the filevault file and configure its bin path to system path variable.
Export project from CQ to local machine
c:\CQ5_training\backup>vlt --credentials admin:admin export -v http://localhost:4505/crx /apps/training .
Above command creates a jcr_root folder in backup folder and put all files from crx
Import Project from Local file system to CQ
c:\CQ5_training\backup>vlt --credentials admin:admin import -v http://localhost:4505/crx . /apps/training
Once user credential is entered, it is not required again bcz, the user credential is saved in user directory> vault folder as an xml file.
Checkout just directory structure, not entire project
backup>vlt -co http://localhost:4505/crx/-/jcr:root/apps/training .

Identify locally modified files, execute below command.
jcr_root>vlt -st

Identify difference in local and crx files, execute below command.
jcr_root>vlt -diff complex/components/test.jsp
jcr_root>vlt diff will give all changed fields comparison in jcr_rot checked out directory

commit changes to code repository:
All files:
jcr_root>vlt - ci
Single file commit:
jcr_root>vlt - ci filename

Note: ci,st,diffcommaond only works withchecked out code , not exported code.

-------Similar Posts---------------
Mapping of requests in AEM
Interact With AEM
Run Modes
AEM
Apache Sling in AEM

-------------------------------------

Filevault commands reference:
Command             Description
export             Export the Vault filesystem

  import            Import a Vault filesystem

  checkout (co)      Checkout a Vault file system

  analyze            Analyze packages

status (st)        Print the status of working copy files and directories.

update (up)        Bring changes from the repository into the working copy.

info               Displays information about a local file.

commit (ci)        Send changes from your working copy to the repository.

revert (rev)       Restore pristine working copy file (undo most local edits).

resolved (res)     Remove 'conflicted' state on working copy files ordirectories.

propget (pg)       Print the value of a property on files or directories.

proplist (pl)      Print the properties on files or directories.

propset (ps)       Set the value of a property on files or directories.

add                Put files and directories under version control.

delete (del,rm)    Remove files and directories from version control.

diff (di)          Display the differences between two paths.

rcp                Remote copy of repository content.

  sync               Control vault sync service

  console            Run an interactive console