Expand my Community achievements bar.

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