Expand my Community achievements bar.

Enhance your AEM Assets & Boost Your Development: [AEM Gems | June 19, 2024] Improving the Developer Experience with New APIs and Events
SOLVED

How to create sling events for specific templates in aem?

Avatar

Level 9
I want to make an external call whenever the page is published and I don't want to do this for all pages. Only certain pages I want to do this call. For example for the page is created with /conf/abc/template template.(cq:template = /conf/abc/template)
 
Could anyone tell me what sling event API to use for this requirement ?
 
1 Accepted Solution

Avatar

Correct answer by
Level 9

@Mario248 : Every template has a resource type, I believe you can make use of that instead of template name. Also, you can use this in combination with path as well.

@Component(service = EventHandler.class, immediate = true, property = {
Constants.SERVICE_DESCRIPTION + "=Event Handler ",
EventConstants.EVENT_TOPIC + "="+ReplicationAction.Event_Topic,
EventConstants.EVENT_FILTER + "= ((path=/content/your-site/*)(resourceType=myapp/components/page/your-page-component))" })

You can refer this :- https://experienceleaguecommunities.adobe.com/t5/adobe-experience-manager/event-filter-is-not-workin...

https://techagyan.blogspot.com/2015/02/aem-event-handling-and-filtering.html

 

thanks.

 

View solution in original post

8 Replies

Avatar

Community Advisor

Hi @Mario248 

 

You can use ResourceChangeListener class to handle sling level events and below is the sample code and you can customize it according to your business logic.

import org.apache.sling.api.resource.observation.ResourceChange;
import org.apache.sling.api.resource.observation.ResourceChangeListener;
import org.osgi.service.component.annotations.Component;

@Component(service = ResourceChangeListener.class,
           property = {
                   "sling.resourceType=/conf/abc/temp1", // Target the specific template
                   "path=/content/(.*)" // Observe page creation under content
           })
public class PageCreationEventHandler implements ResourceChangeListener {

    @Override
    public void onChange(ResourceChange change) {
        if (change.getType() == ResourceChange.Type.ADDED) {
            // Page has been created
            String pagePath = change.getPath();

            // Your custom logic here
            System.out.println("Page created: " + pagePath);
            // Example: Send a notification, perform additional processing, etc.
        }
    }
}


Hope it helps.

Avatar

Level 9

Thanks for your response. You are using ResourceChangeListener over sling events. Is there any preference and suggestion?

Avatar

Employee Advisor

The ResourceChangeListener is the recommended approach, as sending all repository changes as OSGI events is not scalable enough. Also you need to handle all requests, you cannot limit your listener be called only for a certain path(s).

Avatar

Community Advisor

@Mario248 

I think @Jörg_Hoh  mentioned the reason behind using ResourceChangeListener. I hope that helps.

Avatar

Correct answer by
Level 9

@Mario248 : Every template has a resource type, I believe you can make use of that instead of template name. Also, you can use this in combination with path as well.

@Component(service = EventHandler.class, immediate = true, property = {
Constants.SERVICE_DESCRIPTION + "=Event Handler ",
EventConstants.EVENT_TOPIC + "="+ReplicationAction.Event_Topic,
EventConstants.EVENT_FILTER + "= ((path=/content/your-site/*)(resourceType=myapp/components/page/your-page-component))" })

You can refer this :- https://experienceleaguecommunities.adobe.com/t5/adobe-experience-manager/event-filter-is-not-workin...

https://techagyan.blogspot.com/2015/02/aem-event-handling-and-filtering.html

 

thanks.

 

Avatar

Level 9

Thank for your reply. For some reason the sling resource type is common for other pages hence I have to reply on cq:template property hence I tried below code but it is not working. any reason ?

 

@Component(service = EventHandler.class, immediate = true, property = {
Constants.SERVICE_DESCRIPTION + "=Event Handler ",
EventConstants.EVENT_TOPIC + "="+ReplicationAction.EVENT_TOPIC,
EventConstants.EVENT_FILTER + "= ((cq:template=/conf/abc/template))" })

Avatar

Level 9

@Mario248 : In that case, you will have to create an EventHandler at a path level to reduce triggering of it everywhere and then in handleEvent method you can apply the filter based on cq:template property.

    @Override
    public void handleEvent(Event event) {
ReplicationAction replicationAction = ReplicationAction.fromEvent(event);
String pagePath = replicationAction.getPath();
//read the jcr:content/cq:template property value and check if it matches with your template. based on the match you can take action.
    }

Avatar

Level 9

Thank, But this particular service is triggered for all the pages and we are checking and filtering based on cq:template which is kind of okay but this service/component gets fired for all aem pages. Is there any filter which we can apply before this stage?