Expand my Community achievements bar.

Don’t miss the AEM Skill Exchange in SF on Nov 14—hear from industry leaders, learn best practices, and enhance your AEM strategy with practical tips.
SOLVED

Convert a Component into Experience Fragment with custom sling:resourceType

Avatar

Level 2

Hello Team,

 

When I convert a component into Experience fragment using 'convert to experience fragment variation', the experience fragment is getting created with 'sling:resourceType: cq/experience-fragments/editor/components/experiencefragment'.

 

xf1.PNG

But I want to replace the sling:resourceType with our custom Experience Fragment component path.

As checked, a servlet call has been posted to 'http://localhost:4502/libs/cq/experience-fragments/content/v2/conversion/converter'.

It calls a servlet 'ConvertToExperienceFragmentVariation' from 'com.adobe.cq.cq-experience-fragments' bundle.

But I could not extend the servlet as it is not part of the uber jar file. 

 

Can anyone guide me how to proceed with the requirement? Thanks in advance.

 

 

1 Accepted Solution

Avatar

Correct answer by
Level 2
package com.demo.core.filters;

import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;
import static org.apache.sling.engine.EngineConstants.*;

import org.apache.sling.api.resource.ModifiableValueMap;
import org.apache.sling.api.resource.Resource;
import org.osgi.service.component.annotations.Component;
import org.osgi.framework.Constants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import java.io.IOException;

@Component(service = Filter.class, name = "Custom Experience Fragment Path Update Filter", property = {
		SLING_FILTER_SCOPE + "=" + FILTER_SCOPE_REQUEST, Constants.SERVICE_RANKING + ":Integer=-100",
		SLING_FILTER_PATTERN + "=/libs/cq/experience-fragments/content/v2/conversion/converter" })

public class ExperienceFragmentFilter implements Filter {
	private static final Logger log = LoggerFactory.getLogger(ExperienceFragmentFilter.class.getName());

	// Called by the web container to indicate to a filter that it is being placed
	// into service.

	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
	}

	// Called by the web container to indicate to a filter that it is being taken
	// out of service.
	@Override
	public void destroy() {
	}

	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
			throws IOException, ServletException {

		chain.doFilter(request, response);
		if (request instanceof SlingHttpServletRequest && response instanceof SlingHttpServletResponse) {

			// Do work before sending the request down the Filter AND Sling processing chain
			final SlingHttpServletRequest slingRequest = (SlingHttpServletRequest) request;
			String componentPath = slingRequest.getParameter("componentPaths");
			log.info("Component path in filter is  ---->"+componentPath);
			Resource componentRes = slingRequest.getResourceResolver().resolve(componentPath);
			if(componentRes!=null)
			{
				ModifiableValueMap map = componentRes.adaptTo(ModifiableValueMap.class);
				log.info("current resource type --->"+map.get("sling:resourceType"));
				map.put("sling:resourceType", "<custom_component_path>");
				componentRes.getResourceResolver().commit();
				log.info("Successfully updated component path");
			}
			// The Request/Response have now been fully processed by Sling/AEM

		} else {
			// Else process the chain as usual.
			chain.doFilter(request, response);
			return;
		}

	}

}

 This can be achieved by implementing custom sling filter and updating sling:resourceType value. Above code does that, just update <custom_component_path> with your component path and this should work. I have tested this code on 6.5.10 version

View solution in original post

2 Replies

Avatar

Correct answer by
Level 2
package com.demo.core.filters;

import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;
import static org.apache.sling.engine.EngineConstants.*;

import org.apache.sling.api.resource.ModifiableValueMap;
import org.apache.sling.api.resource.Resource;
import org.osgi.service.component.annotations.Component;
import org.osgi.framework.Constants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import java.io.IOException;

@Component(service = Filter.class, name = "Custom Experience Fragment Path Update Filter", property = {
		SLING_FILTER_SCOPE + "=" + FILTER_SCOPE_REQUEST, Constants.SERVICE_RANKING + ":Integer=-100",
		SLING_FILTER_PATTERN + "=/libs/cq/experience-fragments/content/v2/conversion/converter" })

public class ExperienceFragmentFilter implements Filter {
	private static final Logger log = LoggerFactory.getLogger(ExperienceFragmentFilter.class.getName());

	// Called by the web container to indicate to a filter that it is being placed
	// into service.

	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
	}

	// Called by the web container to indicate to a filter that it is being taken
	// out of service.
	@Override
	public void destroy() {
	}

	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
			throws IOException, ServletException {

		chain.doFilter(request, response);
		if (request instanceof SlingHttpServletRequest && response instanceof SlingHttpServletResponse) {

			// Do work before sending the request down the Filter AND Sling processing chain
			final SlingHttpServletRequest slingRequest = (SlingHttpServletRequest) request;
			String componentPath = slingRequest.getParameter("componentPaths");
			log.info("Component path in filter is  ---->"+componentPath);
			Resource componentRes = slingRequest.getResourceResolver().resolve(componentPath);
			if(componentRes!=null)
			{
				ModifiableValueMap map = componentRes.adaptTo(ModifiableValueMap.class);
				log.info("current resource type --->"+map.get("sling:resourceType"));
				map.put("sling:resourceType", "<custom_component_path>");
				componentRes.getResourceResolver().commit();
				log.info("Successfully updated component path");
			}
			// The Request/Response have now been fully processed by Sling/AEM

		} else {
			// Else process the chain as usual.
			chain.doFilter(request, response);
			return;
		}

	}

}

 This can be achieved by implementing custom sling filter and updating sling:resourceType value. Above code does that, just update <custom_component_path> with your component path and this should work. I have tested this code on 6.5.10 version