Skip to main content

Adobe

Create Custom Datasource for Dropdown Fields in Context-Aware Config Editor

Developers Guide To Custom Datasource For Dropdown Fields In Context-Aware Configuration Editor

Sling Context-Aware Configuration in AEM (Adobe Experience Manager) provides the flexibility to set key value pairs for a business logic specific to a content path instead of site-wide configuration or template-wide configuration.  For example, if you want to set different values for path /content/mysite/en and /content/mysite/es, then we can use the Context-Aware Configuration at the specific path level.   

These context-aware config values can look as simple as key value pairs with simple text field, to hardcoded drop list to select predefined values for a key.  

The sample code snippet below is for creating a dropdown list using WCM IO.

@Property(label = "My Dropdown", description = "Values for my dropdown.", property = { 

    "widgetType=dropdown", 

    "dropdownOptions=[" 

        + "{'value':'option1','description':'Desc for option1'}," 

        + "{'value':'option2','description':'Desc for option2'}," 

        + "{'value':'option3','description':'Desc for option3'}" 

        + "]" 

}) 

String sampleDropDownParameter();

From a business user point of view, we like to have dynamic values in the drop-down list so that we don’t have to wait for another code deployment.   

From a developer’s point of view, in this blog, I am going to show how to solve the above requirement.  

With WCM IO Editor extension we can implement DataSource to provide these dropdown values which makes behavior consistent especially if we are using the same source for other places. Then we can simply use the same data source in our custom data source implementation. 

It provides DropdownOptionsProvider class to which we need to implement and write our custom logic. 

Let’s consider we are writing dropdown options for providing the list of template paths which is required for some sort of mapping.  

We will implement DropdownOptionsProvider which will also have configuration ability where we will provide the root path of the templates. 

/** 
 * Implementation for Template Path Data source for CAC. 
 */ 
@Component(service = DropdownOptionProvider.class, 
        immediate = true, property = {"io.wcm.caconfig.editor.widget.dropdown.provider=templateDataSource"}) 
@ServiceDescription("Implementation For DropdownOptionProvider For Providing Templates Path ") 
@Slf4j 
@Designate(ocd= TemplatesDatasourceServiceImpl.Configuration.class) 
public final class TemplatesDatasourceServiceImpl implements DropdownOptionProvider { 
 
    private Configuration configuration; 
 
    @Activate 
    @Modified 
    public void activate(final Configuration configuration){ 
        this.configuration = configuration; 
    } 
 
    @Override 
    public @NotNull List<DropdownOptionItem> getDropdownOptions(@NotNull final Resource resource) { 
        final List<DropdownOptionItem> dropdownOptionItems = new ArrayList<>(); 
        final var resourceResolver = resource.getResourceResolver(); 
        final var templatesResource = resourceResolver.getResource(configuration.template_path()); 
        dropdownOptionItems.add(new DropdownOptionItem("ALL", "ALL - To be used for mapping in All templates")); 
        if (templatesResource != null) { 
            templatesResource.getChildren().forEach(templateResource -> { 
                final var contentResource = templateResource.getChild("jcr:content"); 
                final var contentResourceProps = Optional.ofNullable(contentResource) 
                        .map(Resource::getValueMap).orElse(new ValueMapDecorator(new HashMap<>())); 
                final var title = contentResourceProps.get("jcr:title", String.class); 
                final DropdownOptionItem dropdownOptionItem = 
                        new DropdownOptionItem(templateResource.getPath(), title + "|" 
                                + templateResource.getPath()); 
                dropdownOptionItems.add(dropdownOptionItem); 
            }); 
        } 
        return dropdownOptionItems; 
    } 
 
    @ObjectClassDefinition(name = "Template Path For Mappings") 
    public @interface Configuration { 
        @AttributeDefinition( 
                name = "Template Paths" 
                , description = "Template Paths" 
        ) 
        String template_path() default "/conf/we-retail/settings/wcm/templates"; 
    } 
 
 
}

We can see that Configuration provides the ability to configure the template root path. Here we are just setting we-retail path as default path. 

io.wcm.caconfig.editor.widget.dropdown.provider=templateDataSource 

This will register our data source with the name of templateDataSource which we can use in Annotating the dropdown property. 

@Property(label = "Select Template Name/Path", description = "Name Of Template to be mapped.", property = { 
        "widgetType=dropdown", 
        "dropdownOptionsProvider=templateDataSource" 
}, order = 1) 
String getTemplatePath();

It will appear in the editor window as pictured below.

We Retail Templates

We can see it dynamically populated all the We Retail templates. 

We can update logic according to required conditions like using existing Generic Lists, Pages, or any Third-party API calls. 

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Saurabh Mahajan, Lead Technical Consultant

Saurabh is certified Adobe Experience Manager Sites Architect.

More from this Author

Categories
Follow Us