Skip to main content

Adobe

AEM Development Quick Tip: Component Unique ID

Often times, you need a unique ID for the AEM component. You either need to trigger custom action with JS or make a backend server side call. A hard-coded field ID is not unique if the component is dragged and dropped multiple times in the page. This post will give you a quick tip to create a unique component ID in AEM, the Adobe way.
When you are thinking about ID, you may think of using the global HTL objects and getters directly, for example: ${currentNode.name}. However, this will not solve the problem if the component is used in different containers on the same page. How about ${currentNode.identifier}? While this JCR node level API returns a unique id for the current node, it contains the node path and forward slashes in the id, which exposes internal content structure and makes it difficult to use in CSS and JS without escaping.
The way Adobe implements it is to generate from resource path, with an ID prefix variable. The core of this solution is that ID can be injected from JCR content directly, or generated from resource path. For example, if you have an OSGI service or dialog that saves the component ID attribute in JCR, it will honor and use that, instead of generating a new one. If the component doesn’t have an ID attribute, the solution will forms the ID by cascading an ID prefix, hyphen and hash code of the component’s resource path. We know that resource path will always be unique even the component is used multiple times and in a different level of containers. The hash code encapsulates and hides internal path information to end user, and makes the id attribute easily used by CSS and JS. To make the ID attribute more human readable, developer passes in the ID prefix. Below is a snippet of AbstractComponentModel.java. Component sling model should extend this class and override the getIDPrefix().

public abstract class AbstractComponentModel {
  @ValueMapValue(injectionStrategy = InjectionStrategy.OPTIONAL)
  protected String id;
  protected abstract String getIDPrefix();
  @SlingObject
  private Resource resource;
  public String getId() {
    if (id == null) {
      id = getIDPrefix() + "-" + String.valueOf(Math.abs(resource.getPath().hashCode() - 1));
    }
    return id;
  }
}

I have implemented this solution for title component in my blog demo project. I updated the POM files and tested the code in AEM 6.4. The latest code is in master branch, where it’s runnable in AEM 6.4. I also created a “release/aem-6.3” branch for my previous code that’s deployable in AEM 6.3. Below is a screenshot of what the title component ID looks like.
 
We’d love to hear from you! Leave a comment and share any additional thoughts or insights you have.

Thoughts on “AEM Development Quick Tip: Component Unique ID”

  1. I encountered this situation and it seemed pretty helpful. One question what do you think of the combination ${currentnode.name} + “”. Would there be any side effects?

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.

Follow Us