CMS, Java

Working with AEM community components

Goals & Objectives

To understand how to use community components and learn about the SRP API to play with the community components.

How to overlay AEM community components and using in a project, which does not use community templates?

This is almost similar to how we overlay AEM OOTB components. However, there are few tweaks to be done to get going.

  • Using CRXDE Lite on an author instance, start by creating a path in the /apps folder which is similar to the path to the overlaid components in the /libs folder.
  • Need to add “” as a dependency to your project global client-library as it has to be loaded first.
  • There are few other dependencies to be added to the projects client library which can be determined from here http://localhost:4502/content/community-components/en.html (Community component guide) where we can find dependencies for a particular community component.
  • For example, Navigate to http://localhost:4502/content/community-components/en/calendar.html to find the required client libraries for calendar component as shown below.



  • Add “cq.ckeditor,,” as dependencies to the projects clientlibrary.
  • You may be wondering why these dependencies are needed to begin with. These dependencies are added automatically to the page whenever you use the community template. You will also see a node titled “clientlibslist” with the property “scg:requiredClientLibs” having few client libraries included. Since we are not using community templates in our case, these dependencies need to be added manually. This is critical for the community components to work properly without any issues.
  • Give category name to the overlaid components client-library and embed it to the project client-library.

About SRP

All the AEM Communities features and components are developed using social component framework (SCF), which invokes the SocialResourceProvider API to access all user-generated-content (UGC).

Before working with community components, the storage resource provider (SRP) must be configured. There are three storage options:

  • ASRP – Adobe on-demand storage
  • MSRP – MongoDB
  • JSRP – JCR

More details about accessing UGC with SRP can be found here (

Working with SRP API

While working with community components or developing custom components, assume that JCR is not available. Methods related to JCR API must be avoided. Use Sling API instead. The SocialResourceProvider API (SRP API) is an extension of various Sling Resource Provider APIs. Custom code should use methods from UGC API package ( which will invoke the query language appropriate for the chosen SRP.

Following is an example of using the community-liking component and finding the pages, which are liked.

Accessing the UGC storage path.

SocialResourceUtilities socialUtils = getSlingScriptHelper().getService(SocialResourceUtilities.class);
String path = socialUtils.getStorageConfig(getResource()).getAsiPath();
SearchResults<Resource> results = getResources(getResourceResolver(), 10, path + Constants.ROOT_PATH, user);

Filtering results based on the constraints like path, values and the results can be sorted as well:

private SearchResults<Resource> getResources(final ResourceResolver resolver, final int num, final String path,
 final String user) throws RepositoryException {
 UgcFilter filter = new UgcFilter();
 filter.addConstraint(new PathConstraint(path, PathConstraintType.IsDescendantNode));
 filter.addConstraint(new ValueConstraint("userIdentifier", user, ComparisonType.Equals));
 new ValueConstraint("sling:resourceType", "social/tally/components/hbs/liking", ComparisonType.Equals));
 filter.addConstraint(new ValueConstraint("response", "1", ComparisonType.Equals));
 filter.addSort(new UgcSort("timestamp", Direction.Desc));

 SearchResults<Resource> results = ugcSearch.find(null, resolver, filter, 0, num, true);
 return results;

All the filtering methods can be found under the class “”.

Un-liking functionality is already built-in but can be invoked in other situations when required as:

 private TallyOperationsService tallyOperationsService;

 protected void doPost(SlingHttpServletRequest request, SlingHttpServletResponse response)
 throws ServerException, IOException {

 String path = request.getParameter("ugcPath");
 Resource res = request.getResourceResolver().resolve(path);

 try {
 tallyOperationsService.removeCurrentUserResponse(res.getParent(), "Liking");
 } catch (OperationException e) {
 log.error("Exception occurred while unliking", e);

Also when creating custom properties that are searchable, it is necessary to follow naming conventions. In order for those custom properties to be visible to searches and sorts created using UGC search API, it is mandatory to add the suffix to the property name. for example, “order_s” is the custom property visible for sorts and searches.

The custom properties can be added to the respective resource using Sling API. For example,

Resource res = resolver.resolve(value[0]);
ModifiableValueMap vm = res.adaptTo(ModifiableValueMap.class);
Long val = Long.parseLong(key);
vm.put("order_s", val);

Disclaimer: Please note that the above code snippets are provided as a reference sample and should be used as a starting point.

About The Author

Leave a Reply