List Core Component exclude child pages based on a property

gautamg99016783

07-06-2020

We are extending the List Core Component to display a list of child pages on the parent page.We have a requirement where our marketing partners can exclude some pages so that they are not eligible for being displayed in the list component. We are planning to have a checkbox in page properties. Only when this checkbox is checked for a child page, that child page will be eligible to be shown in list component.So basically only the pages that have this checkbox checked will be processed in the backend and then returned to UI if they meet other existing criteria. For eg, let's say there are 5 child pages under a parent page, but only 3 have this checkbox checked. Let's say a now user wants to see 4 child pages on the List Component, but he will only see the 3 that have this checkbox checked. 

 

How can we achieve this? There are methods populateChildListItems() and collectChildren(int startLevel, Page parent) which are populating the list of child pages and seems this check to exclude pages based on this property can be done there. But how can we "override" these private methods in our custom implementation?

Accepted Solutions (1)

Accepted Solutions (1)

Nupur_Jain

MVP

07-06-2020

Hi @gautamg99016783 

 

In order to achieve required changes, you will have to implement the existing Adobe WCM list Model Interface in your own List model. Follow these steps:

  • If you look at the core component list.html file, it uses the Adobe List Model

 

<ul data-sly-list.item="${list.items}"
    data-sly-use.list="com.adobe.cq.wcm.core.components.models.List"
    data-sly-use.template="core/wcm/components/commons/v1/templates.html"
    data-sly-use.itemTemplate="item.html">
    <li data-sly-call="${itemTemplate.item @ list = list, item = item}"></li>
</ul>
<sly data-sly-call="${template.placeholder @ isEmpty=list.items.size == 0}"></sly>​

 

 

Here, com.adobe.cq.wcm.core.components.models.List is an Interface, you do not need to overlay this file as we will provide our own implementation of List.java interface

  •  In your code base, add dependency to core components in pom.xml

 

            <dependency>
                <artifactId>core.wcm.components.core</artifactId>
                <version>2.2.0</version>
                <groupId>com.adobe.cq</groupId>
                <scope>provided</scope>
            </dependency>
​

 

Make sure to change version as per your running AEM instance

  • Create your  new model Class which implements com.adobe.cq.wcm.core.components.models.List

 

import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.models.annotations.Model;

import com.adobe.cq.wcm.core.components.models.List;

@Model(adaptables = SlingHttpServletRequest.class, adapters = List.class,
resourceType = "my-project/components/content/my-list")

public class MyList implements List{
		
   //Give your own implementations of the methods

}​

 

The resourceType here must be the resourceType of your list component

  • We can not change/use/extend List implemetation of adobe as it is not exported by Core components bundle but since it is open source, we can create our own implementation. 
    https://github.com/adobe/aem-core-wcm-components/blob/master/bundles/core/src/main/java/com/adobe/cq... is the WCM core components internal implementation. You can copy everything and make changes. Make sure to use implementation as per core components version. This one is for v1.
  • Deploy and test if your own list implementaion is getting picked up.

Try out and let me know.

 

Thanks,

Nupur

Answers (2)

Answers (2)

gautamg99016783

16-06-2020

The solution proposed would need adding a lot of overriden code. So we found this alternate way. This seems much cleaner.

 

We converted the OOTB maxItems field to a hidden field and set it to 0, which means ALL child pages will be read from the backend everytime since the value of this field is used ti fetch data. Then we added a new numberfield itemsToDisplay, which the authors will use to select the number of children to show in the List. This field behaves exactly like the maxItems would. So from an author's perspective nothing is changed.

 

Then in our Java code we will get all child pages and then use the value of itemsToDisplay to select the required number of items to display in the List.

 

Screen Shot 2020-06-16 at 5.54.11 PM.png

manising

07-06-2020

One way I can think of is that you can uncheck the read permissions for the group when the check option is clicked programmatically. This way you can ensure that only the pages with read permissions are returned.