Friday, January 30, 2015

Custom synchronisation or rollout action for blueprint ?

Blueprint is an important feature for all those sites which needs to deals with multiple locale and region specific sites. Consider that we have 20 different regional sites and each regional site have 2 locales (English and regional language). Now let’s say you need to do a small update on a English locale page and that changes is required on all sites, there will be 20 pages that you’ll need to visit and make changes one by one (if you have not used blueprint and live copy).

With blueprint  we can create a master copy (which is called as blueprint) and create many live copies (which are actual sites) and the benefit you get is that as soon as you do any change in blueprint that same change will be propagated to all live copies pages when changes are rolled out by authors…this is cool. With blueprint you’ll need to apply changes only to English locale page on blueprint and all English locale pages (live copies) will receive that change implicitly.

So, how this whole thing works? Whenever a blueprint is created we need to define rollout configurations. Rollout configurations tell what to do when a blueprint page is updated. Rollout configuration consist A Trigger and Single/Multiple Actions:

1) Trigger: this is a string value (either of “rollout”, “modification”, “publish” etc.) which tells when to trigger (rollout) a particular action on blueprint.

2) Action (cq: LiveSycnAction): this is actual action performed on blue print. Action can be content update, content copy, content delete, references update, order children etc.



AEM provides default triggers and actions that you can combine to suffice your need. Sometimes you may want to perform a custom action (e.g. send an email to author when a blueprint page is updated). In this article we are going to see how to develop custom LiveSyncAction. If you want to understand blueprint, live copy and MSM completely then please go through the links mentioned in reference section of this article.

As you can see in above diagram, a rollout configuration is combination of trigger and multiple (or single) actions. Each node in above diagram represents an action, and “jcr:primaryType” of these action nodes is “cq:LiveSyncAction”.


To create a custom LiveSyncAction we need to understand following classes:

1) com.day.cq.wcm.msm.api.LiveActionFactory and com.day.cq.wcm.msm.api.LiveAction
a. LiveActionFactory: An Factory used to create LiveActions. Used to register LiveAction implementations with the ServiceComponentRegistration (in Felix Console) It enables to create LiveActions with a Configuration given by a Resource.
b. LiveAction: Represent an Action to be performed upon a Roll-out from a Source to a Target. Actions are created by a LiveActionFactory that provide instances of LiveActions set-up with given configuration. LiveActions are called during the process of roll-out which on acts on Resources A LiveAction must therefore act within the boundary of the given Resource

2) com.day.cq.wcm.msm.impl.actions.BaseActionFactory and com.day.cq.wcm.msm.commons. BaseAction
a. BaseActionFactory: Base implementation of a LiveActionFactory service. We do have other action factory class that provides fileting options. FilteredActionFactoryBase is a BaseActionFactory extension that provides basic support to set-up filtering configuration.
b. BaseAction: Base implementation for the LiveAction interface. This abstract class offers some basic configuration tasks for building a LiveAction and also default implementations for the deprecated methods. It will speed up the implementation of a LiveAction by only implementing the handles and doExecute abstract methods.

To create a custom LiveAction we need to create a factory by extending “BaseActionFactory” class and implement actual action by extending “BaseAction” class and fill login in doExecute() method. All live actions in AEM are registered with OSGi/Felix console.




Here is a sample class that implements a custom LiveAction to send emails (ignore errors shown below as I don't have dependencies in my maven repo).


Once a live action has been created and corresponding OSGi bundle has been installed in OSGi/Felix container go to Felix console and open OSGi-> Services tab and verify that “SendMailActionFactory” has been register similar to figure 2 above. If action factory has been registered then we are good to use newly create live actions.

How to use newly created custom live action:
1) Go Tools (https:///miscadmin#/etc/msm/rolloutconfigs) 
2) From right hand side menu select [New… -> New Page…] enter title and name (e.g. test and test for both)



3) Go to CRXDELite and open navigate to /etc/msm/rolloutconfigs
4) You should see a page/node (test) for newly create page in step# 2
5) Under the “test” node navigate to “jcr:content” node (/etc/msm/rolloutconfigs/test/jcr:content)
6) Create a new node with name “sendMailAction” of type “cq:LiveSyncAction” and click “Save All…”.
Note that node name (i.e. “sendMailAction”) should match with the “LIVE_ACTION_NAME” static final variable defined in SendMailActionFactory class because we have registered our custom action in AEM container with that name.



7) We have created a rollout configuration and it is ready for use. Now when you go to “Blueprint” tab on page properties, you should get a new rollout config option.




References:
http://docs.adobe.com/docs/en/cq/current/administering/multi_site_manager.html
http://docs.adobe.com/docs/en/cq/current/developing/multi_site_manager_dev.html#par_title

Wednesday, January 28, 2015

How to create a page with predefined components?


Templates and components are core assets/building blocks of any AEM project and provide a capability to content authors to update pages/content.

Many times we want to create pages with some default components prefilled/configured/dropped on a newly created page with an option for authors where they can remove any component (if it is not required).

Let’s consider a scenario/use case where this can be applied. Let’s say we have photo album site where author can create new albums/pages using a photo album template. A photo album page has some space reserved on right hand side for displaying popular images and newly added images. Both of these components are dropped inside a parsys.


Now, if author wants to create an album page he needs to create a page and then drop components one by on the newly create page. Is there a way to have a page prefilled with all the components so that author doesn’t need to add them one by one? Yes, this is what we are going to cover in this article.

Follow these steps to have a template preconfigured with some default components:

1) Create a new page and drop all required components on that page. In our case, we’ll create a new album page and will drop “photo album”, “popular images” and “newly added” component.
2) Go the CRXDELite and explore the newly created page and nodes under it. You’ll see that with there are 2 parsys nodes one of them has “photo album” and another parsys node have “popular images” and “newly added” component nodes.
3) Go the template in apps folder using which page has been created (e.g. (/apps/photogallery/templates/albumpage) and as you can see it by default contains “jcr:content” node.
4) Now copy both parsys nodes from album page that we have created in step#1 to jcr:content node of template (albumpage). At this point the structure of jcr: content should match the with node structure of actual album page.
5) Create a new album page using the same template (i.e. (/apps/photogallery/templates/albumpage) and now when you open the page you’ll see that newly created page already contains all the components on it.

So, how does this works? A template node in CQ/AEM is of type cq:template and the default behaviors this node is doing all the work for us. Basically whatever properties/nodes that we have at template’s jcr:content level will be copied over to a newly created page’s node. 


Get in the Vibe with Copilot Agent: Supercharging Your Coding Flow

Have you ever felt "in the zone" while coding? That feeling of seamless flow, where the code practically writes itself? That's...