Context Aware Configuration : Context Path Strategy



I was working on a solution which involves introduction of sling context aware configuration to the application. When I explain the design to my manager, he agreed on all implementation steps except the default mapping of configuration with content using sling:configRef property. He pointed me out some of the challenges that may come while adding the property to the already running multi-locale site with experience fragments.

Since the design was so impressive, I was keen to implement it somehow with very less interference with  content. So I started searching for a way more suitable to our requirement and I found something called "Context Path Strategy". This is something not very new but availability of resources specially for new developer are very limited so thought of walking through the implementation via this post.

So what this Context Path Strategy is ?

To implement context aware configuration, you will have to set sling:configRef property to every parent nodes of your content tree so that all the nodes under the tree will become a context and the configuration will be applied to it. For example if you have multi locale site with  structure as

/content/ └── mysite/ ├── us/ │ └── en/ ├── zh/ │ └── cn/ └── ja/ 
└── jp/

and you need to apply site specific configuration, in this case you will have to add sling:configRef property to us, zh and ja content node respectively. This is where the problem was (in my case) and it was solved with the help of context path strategy. It means the context path strategy is something which will help you to implement context aware configuration without setting the property to every nodes of your content tree.

You just set the property at your site root level (mysite in above example) and rest other stuff will be taken care by an osgi config.

There are two context path strategy available as Absolute Parents and Root Templates.

How I implemented it?

I will be talking about Absolute Parents strategy here. Once you are done with the implementation of context aware configuration I followed below steps:

  1. Inside ui.content module, I added two nodes, one for site and another for experience fragment under content as 

    2. add sling:configRef property with its value thru .content.xml for the node as 


Above two steps are optional, as I don't had option to set the property directly to the content so I set it thru code for pages and experience fragment but it depends on your use case. If you have to follow above two steps DON'T FORGET TO USE MODE=UPDATE for the path IN FILTER.XML OF THE MODULE OTHERWISE YOU WILL BE IN BIG TROUBLE.


    3. Next I added dependency for io.wcm.caconfig.extensions in your all/pom.xml and embedded this with filevault plugin as 


again all/pom.xml is not the only place ,where you have to add those, you can add it in another modules pom.xml as well based on your implementation.


    4. Created an OSGI configuration for io.wcm.caconfig.extensions.contextpath.impl.AbsoluteParentContextPathStrategy-mysite.cfg.json with below properties
{
"levels:int[]":[4,5],
"contextPathRegex":"^/content/(experience-fragments/mysite-fragments|mysite)(/.*)?$",
"configPathPatterns":[
"/conf/mysite/ca-configs/$2"
],
"templatePathsBlacklist":[]
}

before explaining above properties It will be better if I can put my content and configuration node structure here:

Content:
  • Pages:
             /content/             └── mysite/                  ├── us/                         └── en                 ├── zh/                     └── cn                 └── ja/                          └── jp
 
  •  Experience Fragments:
                       
       /content         └── experience-fragments         └── mysite-fragments          ├── us/         │ └── en          ├── zh/          │ └── cn         └── ja/          └── jp

Context aware configs:

└── /conf/
└── mysite/
└── ca-configs/
├── us/
│ └── en/
│ └── sling:configs/
│ └── com.mysite.aem.services.config.SiteConfiguration
├── zh/
│ └── cn/
│ └── sling:configs/
│ └── com.mysite.aem.services.config.SiteConfiguration
└── ja/
└── jp/
└── sling:configs/
└── com.mysite.aem.services.config.SiteConfiguration

Here is the explanation of above properties:

The levels parameter indicates the depth at which the context configuration will be applied in your content hierarchy. Let's break it down for your content path:

  • Example Path: /content/experience-fragments/mysite-fragments/language-masters/en_us
    • /content is Level 1
    • /content/experience-fragments is Level 2
    • /content/experience-fragments/mysite-fragments is Level 3
    • /content/experience-fragments/mysite-fragments/us is Level 4
    • /content/experience-fragments/mysite-fragments/us/en is Level 5

So, for example, if you want the configuration to apply at the 3rd level (/content/experience-fragments/mysite-fragments), you would define that as level 3.   

The contextPathRegex  ensures the strategy is applied to all content under /content/experience-fragments/mysite-fragments, including subdirectories.

The configPathPatterns defines the configuration paths that should be used. In above implementation, I want to apply the configuration located at /conf/mysite/ca-configs, so the pattern is like that.

The contextPathBlacklistRegex contains list of paths that needs to be excluded, if you don't have any this list can be empty.

Adjust your configuration based on your site structure and requirement.


References :

1. https://www.theaemmaven.com/post/the-editor-for-context-aware-configurations

2. https://experienceleaguecommunities.adobe.com/t5/adobe-experience-manager/context-aware-configurations-context-path-strategies/m-p/706104#M174585

3. https://wcm.io/caconfig/extensions/context-path-strategies.html#:~:text=This%20strategy%20detects%20context%20paths,current%20path%20is%20not%20accepted.

Special thanks to @Arun Patidar for answering my question and @Ankit Gupta for raising a valid concern about content.


Happy Coding.

 

Comments

Popular posts from this blog

Common cause for NullPionterException or Null value in Junit test case for sling model in aem

"java.lang.NoSuchFieldError: FACTORY" while running Junit test in AEM codebase

[AEM Package installation issue] : Newer package version com.myapp:myapp.ui.apps:x.x.x-SNAPSHOT was installed externally. Marking as ignored.