Parent Resource ValueMap Value Sling Injector

December 11, 2020

Pulling parent component properties into the child component is currently not supported by Sling Models. If we have a requirement to get a component property or properties from the parent component into the child component, we can do it by:

  • Use JCR API to adapt the Session/ResourceResolver to the respective parent component's node and get the properties.
  • Use the ComponentInhertianceValueMap API to get the inherited property value into the Sling Model.
  • Create a custom method, which iterates through the parent resources unless the resource is of type cq:Page to create a MergedValueMap or look for the property in each resource’s ValueMap.

Parent Resource ValueMap Value injector addresses the scenario in which one or more components have to inherit parent component properties. This annotation functions similarly to the @ValueMapValue annotation; it gets the parent component property into the Sling Model if available. Injections are available when adapting either a Resource or SlingHttpServletRequest object.

Use Cases

I created this feature to maximize code reuse and provide a generic solution to have a parent-child property inheritance.

  • A component with a parsys for dragging in other components. These 'child' components need to read a property from the 'parent' component.
  • A quiz or contest component, which has several steps as sub-components that need to access "FAQ," "Trademark Disclaimer," and "How to" properties of the parent component inside the sub-component HTML file.
  • An accordion or tab component has content set at the base level, and the child components can use the same content without having to re-author them separately.
  • A list component with multiple child components with a common CTA button text and link can share the values by authoring it on the list component.
  • A column-control component that has author-able shared properties can be consumed by the components within the columns.

How to Use

1. Download and install aem-acs-commons package version 4.9.0 or higher.

2. Inject the properties into your component’s sling model using the @ParentResourceValueMapValue injector from ACS AEM Commons.

3. Set the max-level property value if you know the level of the parent or the parent of the parent component, which has the property you need, to avoid overhead. 

Note: If it’s not explicitly set, it will set to default value -1.

@Model(adaptables = {Resource.class, SlingHttpServletRequest.class},
       adapters = {AccordionItem.class, ComponentExporter.class, ContainerExporter.class},
       resourceType = AccordionItemImpl.RESOURCE_TYPE)
@Exporter(name = ExporterConstants.SLING_MODEL_EXPORTER_NAME, extensions = ExporterConstants.SLING_MODEL_EXTENSION)
public class AccordionItemImpl extends BaseModelContainer implements AccordionItem {

   public static final String RESOURCE_TYPE = "aem-activate/components/content/accordion/accordion-item";

   @ParentResourceValueMapValue(injectionStrategy = InjectionStrategy.OPTIONAL, maxLevel = 2, name = JcrConstants.JCR_TITLE)
   private String accordionTitle;

   @ParentResourceValueMapValue(injectionStrategy = InjectionStrategy.OPTIONAL)
   private String ctaButtonText;

   @ParentResourceValueMapValue(injectionStrategy = InjectionStrategy.OPTIONAL)
   private String ctaButtonLink;

   @ValueMapValue(injectionStrategy = InjectionStrategy.OPTIONAL)
   private Boolean enableCta;

}

Learn More

For additional information on the Parent Resource ValueMap Value Sling Injector, visit the official documentation.