Managing configurations in Adobe Experience Manager (AEM) can be challenging, especially when sharing configs across different websites, regions, or components. The Context-Aware Configuration (CAC) framework in AEM simplifies configuration management by allowing developers to define and resolve configurations based on the context, such as the content hierarchy. However, as projects scale, configuration needs can become more intricate, involving nested configurations and varying scenarios.
In this blog, we will explore Nested Context-Aware Configurations and how they provide a scalable solution to handle multi-layered and complex configurations in AEM. We’ll cover use cases, the technical implementation, and best practices for making the most of CAC.
Understanding Nested Context-Aware Configuration
AEM’s Context-Aware Configuration allows you to create and resolve configurations dynamically, based on the content structure, so that the same configuration can apply differently depending on where in the content tree it is resolved. However, some projects require deeper levels of configurations — not just based on content structure but also different categories within a configuration itself. This is where nested configurations come into play.
Nested Context-Aware Configuration involves having one or more configurations embedded within another configuration. This setup is especially useful when dealing with hierarchical or multi-dimensional configurations, such as settings that depend on both global and local contexts or component-specific configurations within a broader page configuration.
You can learn more about basic configuration concepts on Adobe Experience League.
Categorizing Configurations with Nested Contexts
Nested configurations are particularly useful for categorizing configurations based on broad categories like branding, analytics, or permissions, and then nesting more specific configurations within those categories.
For instance, at the parent level, you could define global categories for analytics tracking, branding, or user permissions. Under each category, you can then have nested configurations for region-specific overrides, such as:
- Global Analytics Config: Shared tracking ID for the entire site.
- Regional Analytics Config: Override global analytics tracking for specific regions.
- Component Analytics Config: Different tracking configurations for components that report analytics separately.
This structure:
- Simplifies management: Reduces redundancy by categorizing configurations and using fallback mechanisms.
- Improves organization: Each configuration is neatly categorized and can be inherited from parent configurations when needed.
- Enhances scalability: Allows for easy extension and addition of new nested configurations without affecting the entire configuration structure.
Benefits of Nested Context-Aware Configuration
- Scalability: Nested configurations allow you to scale your configuration structure as your project grows, without creating redundant or overlapping settings.
- Granularity: Provides fine-grained control over configurations, enabling you to apply specific settings at various levels (global, regional, component).
- Fallback Mechanism: If a configuration isn’t found at a specific level, AEM automatically falls back to a parent configuration, ensuring that the system has a reliable set of defaults to work with.
- Maintainability: By organizing configurations hierarchically, you simplify maintenance. Changes at the global level automatically apply to lower levels unless explicitly overridden.
Advanced Use Cases
- Feature Flag Management: Nested CAC allows you to manage feature flags across different contexts. For example, global feature flags can be overridden by region or component-specific feature flags.
- Personalization: Use nested configurations to manage personalized experiences based on user segments, with global rules falling back to more specific personalization at the regional or page level.
- Localization: Nested CAC can handle localization configurations, enabling you to define language-specific content settings under broader regional or global configurations.
Implementation
To implement the nested configurations, we need to define configurations for individual modules first. In the example below, we are going to create SiteConfig which will have some configs along with two Nested configs and then Nested config will have its own attributes.
Let’s define Individual config first. Th they will Look like this:
@Configuration(label = "Global Site Config", description = "Global Site Context Config.") public @interface SiteConfigurations { @Property(label = "Parent Config - Property 1", description = "Description for Parent Config Property 1", order = 1) String parentConfigOne(); @Property(label = "Parent Config - Property 2", description = "Description for Parent Config Property 2", order = 2) String parentConfigTwo(); @Property(label = "Nested Config - One", description = "Description for Nested Config", order = 3) NestedConfigOne NestedConfigOne(); @Property(label = "Nested Config - Two", description = "Description for Nested Config", order = 4) NestedConfigTwo[] NestedConfigTwo(); }
Following with this Nested ConfigOne and NestedConfigTwo will look like this:
public @interface NestedConfigOne { @Property(label = "Nested Config - Property 1", description = "Description for Nested Config Property 1", order = 1) String nestedConfigOne(); @Property(label = "Nested Config - Property 2", description = "Description for Nested Config Property 2", order = 2) String nestedConfigTwo(); }
And…
public @interface NestedConfigTwo { @Property(label = "Nested Config - Boolean Property 1", description = "Description for Nested Config Boolean Property 1", order = 1) String nestedBooleanProperty(); @Property(label = "Nested Config - Multi Property 1", description = "Description for Nested Config Multi Property 1", order = 1) String[] nestedMultiProperty(); }
Note that we didn’t annotate nested configs with Property as this is not the main config.
Let’s create service to read this and it will look like this:
public interface NestedConfigService { SiteConfigurationModel getAutoRentalConfig(Resource resource); }
Implementation of service will be like this:
@Component(service = NestedConfigService.class, immediate = true) @ServiceDescription("Implementation For NestedConfigService") public class NestedConfigServiceImpl implements NestedConfigService { @Override public SiteConfigurationModel getAutoRentalConfig(Resource resource) { final SiteConfigurations configs = getConfigs(resource); return new SiteConfigurationModel(configs); } private SiteConfigurations getConfigs(Resource resource) { return resource.adaptTo(ConfigurationBuilder.class) .name(SiteConfigurations.class.getName()) .as(SiteConfigurations.class); } }
SiteConfigurationModel will hold the final config including all the configs. We can modify getters based on need. So currently, I am just adding its dummy implementation.
public class SiteConfigurationModel { public SiteConfigurationModel(SiteConfigurations configs) { String parentConfigOne = configs.parentConfigOne(); NestedConfigOne nestedConfigOne = configs.NestedConfigOne(); NestedConfigTwo[] nestedConfigTwos = configs.NestedConfigTwo(); //Construct SiteConfigurationModel As per Need } }
Once you deploy the code On site config menu in context editor, it should look like :
We can see it has given us the ability to configure property 1 and property 2 directly but for Nested one it gave an additional Edit button which will take us to configure the Nested Configs and it will look like this :
Since Nested config two is multifield it gives the ability to add an additional entry.
A Powerful Solution to Simplify and Streamline
Nested Context-Aware Configuration in AEM offers a powerful solution for managing complex configurations across global, regional, and component levels. By leveraging nested contexts, you can easily categorize configurations, enforce fallback mechanisms, and scale your configuration management as your project evolves.
Whether working on a multi-region site, handling diverse user segments, or managing complex components, nested configurations can help you simplify and streamline your configuration structure while maintaining flexibility and scalability.
Learn More
Make sure to follow our Adobe blog for more Adobe platform insights!
Source: Read MoreÂ