Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to restrict a component to add only once per page

Tags:

aem

How to restrict a CQ5/Custom component to add only once per page.? I want to restrict the drag and drop of component into the page when the author is going to add the same component for the second time into the same page.

like image 865
VAr Avatar asked Aug 31 '25 01:08

VAr


2 Answers

One option is to include the component directly in the JSP of the template and exclude it from the list of available components in the sidekick. To do so, add the component directly to your JSP (foundation carousel in this example):

<cq:include path="carousel" resourceType="foundation/components/carousel" />

To hide the component from the sidekick, either set:

componentGroup: .hidden

or exclude it from the list of "Allowed Components" using design mode.

If you need to allow users to create a page without this component you can provide a second template with the cq:include omitted.

like image 67
Bruce Lefebvre Avatar answered Sep 02 '25 22:09

Bruce Lefebvre


Thanks Rampant, I have followed your method and link stated. Posting link again : please follow this blog It was really helpful. I am posting the implementation whatever I have done. It worked fine for me. One can definitely improve the code quality, this is raw code and is just for reference.

1.Servlet Filter

Keep this in mind that,if any resource gets refereshed, this filter will execute. So you need to filter the contents at your end for further processing. P.S. chain.doFilter(request,response); is must. or cq will get hanged and nothing will be displayed.

@SlingFilter(generateComponent = false, generateService = true, order = -700,
scope = SlingFilterScope.REQUEST)
@Component(immediate = true, metatype = false)
public class ComponentRestrictorFilter implements Filter {
public void init(FilterConfig filterConfig) throws ServletException {}

@Reference
private ResourceResolverFactory resolverFactory;

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
  throws IOException, ServletException {
WCMMode mode = WCMMode.fromRequest(request);
if (mode == WCMMode.EDIT) {
  SlingHttpServletRequest slingRequest = (SlingHttpServletRequest) request;
  PageManager pageManager = slingRequest.getResource().getResourceResolver().adaptTo(PageManager.class);
  Page currentPage = pageManager.getContainingPage(slingRequest.getResource());
  logger.error("***mode" + mode);
  if (currentPage != null )) {

ComponentRestrictor restrictor = new ComponentRestrictor(currentPage.getPath(), RESTRICTED_COMPONENT);
    restrictor.removeDuplicateEntry(resolverFactory,pageManager);
  }
  chain.doFilter(request, response);
}
 }

   public void destroy() {}
}

2.ComponentRestrictor class

    public class ComponentRestrictor {

      private String targetPage;
      private String component;
      private Pattern pattern;
      private Set<Resource> duplicateResource = new HashSet<Resource>();
      private Logger logger = LoggerFactory.getLogger(ComponentRestrictor.class);
      private Resource resource = null;
      private ResourceResolver resourceResolver = null;
      private ComponentRestrictorHelper helper = new ComponentRestrictorHelper();


      public ComponentRestrictor(String targetPage_, String component_){
        targetPage = targetPage_ + "/jcr:content";
        component = component_;
      }

      public void removeDuplicateEntry(ResourceResolverFactory resolverFactory, PageManager pageManager) {
        pattern = Pattern.compile("([\"']|^)(" + component + ")(\\S|$)");
        findReference(resolverFactory, pageManager);

      }

      private void findReference(ResourceResolverFactory resolverFactory, PageManager pageManager) {
        try {

          resourceResolver = resolverFactory.getAdministrativeResourceResolver(null);
          resource = resourceResolver.getResource(this.targetPage);
          if (resource == null)
            return;
          search(resource);
          helper.removeDuplicateResource(pageManager,duplicateResource);

        } catch (LoginException e) {
          logger.error("Exception while getting the ResourceResolver " + e.getMessage());
        }
        resourceResolver.close();

      }

      private void search(Resource parentResource) {
        searchReferencesInContent(parentResource);
        for (Iterator<Resource> iter = parentResource.listChildren(); iter.hasNext();) {
          Resource child = iter.next();
          search(child);
        }
      }



      private void searchReferencesInContent(Resource resource) {
        ValueMap map = ResourceUtil.getValueMap(resource);

        for (String key : map.keySet()) {
          if (!helper.checkKey(key)) {
            continue;
          }

          String[] values = map.get(key, new String[0]);
          for (String value : values) {
            if (pattern.matcher(value).find()) {
              logger.error("resource**" + resource.getPath());
              duplicateResource.add(resource);
            }
          }
        }
      }
    }

3.To remove the node/ resource Whichever resource you want to remove/delete just use PageManager api

pageManeger.delete(resource,false);

That's it !!! You are good to go.

like image 45
Pratik Rewatkar Avatar answered Sep 02 '25 22:09

Pratik Rewatkar