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

When I drag and drop a component on a page, how can I display the page and all its child pages using sling model.(Example- we-retail and all of its child pages and grand child pages)

Avatar

Level 2
 
1 Accepted Solution

Avatar

Correct answer by
Community Advisor

Hi @Junnu_ravali 

 

Please use the below approach. Here is the sample piece of code with reference to we-retai.

 

Create a POJO with all the required details such as pageTitle and pageLink.

 

public class MenuPojo {

private String pageTitle;
private String pageLink;
private List<MenuPojo> childPages;

public String getPageTitle() {
return pageTitle;
}

public void setPageTitle(String pageTitle) {
this.pageTitle = pageTitle;
}

public String getPageLink() {
return pageLink;
}

public void setPageLink(String pageLink) {
this.pageLink = pageLink;
}

public List<MenuPojo> getChildPages() {
return childPages;
}

public void setChildPages(List<MenuPojo> childPages) {
this.childPages = childPages;
}

}

 

Create the Model class: You can read the currentPage from dialog also. I am reading from OOTB object.

@Model(adaptables = {SlingHttpServletRequest.class, Resource.class}, defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL)
public class TestModel {

private static final Logger log = LoggerFactory.getLogger(TestModel.class);

@ScriptVariable
private Page currentPage;

@SlingObject
private ResourceResolver resourceResolver;

private List<MenuPojo> menuList = new ArrayList<>();

@PostConstruct
protected void init() {
log.info("***** :: init :: Start :: ******");
menuList = currentPage != null ? getFirstLevelItems(currentPage, menuList) : null; // Here you can read the currentPage path dialog also. I am reading it from OOTB object.
log.info("***** :: init :: End :: *****");
}

private List<MenuPojo> getFirstLevelItems(Page rootPage, List<MenuPojo> menuList) {
Iterator<Page> firstLevelChild = rootPage.listChildren();
while (firstLevelChild.hasNext()) {
Page firstLevelPage = firstLevelChild.next();
if (!firstLevelPage.isHideInNav()) {
getMenuList(menuList, firstLevelPage);
}
}
return menuList;
}

private void getMenuList(List<MenuPojo> menuList, Page firstLevelPage) {
MenuPojo navObj = new MenuPojo();
ValueMap firstLevelPageProperties = firstLevelPage.getProperties();
String pathLink = firstLevelPage.getPath();
navObj.setPageLink(pathLink);
navObj.setPageTitle(firstLevelPage.getTitle());
if (firstLevelPage.listChildren().hasNext()) {
List<MenuPojo> secondLevelItemList = new ArrayList<>();
secondLevelItemList = getFirstLevelItems(firstLevelPage, secondLevelItemList);
navObj.setChildPages(secondLevelItemList);
}
menuList.add(navObj);
}

public List<MenuPojo> getMenuList() {
return menuList;
}
}

 HTL Script on Component:

<sly data-sly-use.menuobj="com.lundbeck.vyeptidtc.core.models.TestModel">
<sly data-sly-list.listObj="${menuobj.menuList}">
<li><a href="${listObj.pageLink}">${listObj.pageTitle}</a></li>
<ul>
<sly data-sly-list.childPageDetails="${listObj.childPages}">
<li><a href="${listObj.pageLink}">${childPageDetails.pageTitle}</a></li>
<ul>
<sly data-sly-list.childPageDetail="${childPageDetails.childPages}">
<li><a href="${listObj.pageLink}">${childPageDetail.pageTitle}</a></li>
<sly>
</ul>
<sly>
</ul>
</sly>
</sly>

 

End User view:

asutosh_jena_0-1622438328204.png

asutosh_jena_1-1622438356061.png

Based on the page,it will retrieve child page and show the links.

 

Thanks!

 

View solution in original post

7 Replies

Avatar

Correct answer by
Community Advisor

Hi @Junnu_ravali 

 

Please use the below approach. Here is the sample piece of code with reference to we-retai.

 

Create a POJO with all the required details such as pageTitle and pageLink.

 

public class MenuPojo {

private String pageTitle;
private String pageLink;
private List<MenuPojo> childPages;

public String getPageTitle() {
return pageTitle;
}

public void setPageTitle(String pageTitle) {
this.pageTitle = pageTitle;
}

public String getPageLink() {
return pageLink;
}

public void setPageLink(String pageLink) {
this.pageLink = pageLink;
}

public List<MenuPojo> getChildPages() {
return childPages;
}

public void setChildPages(List<MenuPojo> childPages) {
this.childPages = childPages;
}

}

 

Create the Model class: You can read the currentPage from dialog also. I am reading from OOTB object.

@Model(adaptables = {SlingHttpServletRequest.class, Resource.class}, defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL)
public class TestModel {

private static final Logger log = LoggerFactory.getLogger(TestModel.class);

@ScriptVariable
private Page currentPage;

@SlingObject
private ResourceResolver resourceResolver;

private List<MenuPojo> menuList = new ArrayList<>();

@PostConstruct
protected void init() {
log.info("***** :: init :: Start :: ******");
menuList = currentPage != null ? getFirstLevelItems(currentPage, menuList) : null; // Here you can read the currentPage path dialog also. I am reading it from OOTB object.
log.info("***** :: init :: End :: *****");
}

private List<MenuPojo> getFirstLevelItems(Page rootPage, List<MenuPojo> menuList) {
Iterator<Page> firstLevelChild = rootPage.listChildren();
while (firstLevelChild.hasNext()) {
Page firstLevelPage = firstLevelChild.next();
if (!firstLevelPage.isHideInNav()) {
getMenuList(menuList, firstLevelPage);
}
}
return menuList;
}

private void getMenuList(List<MenuPojo> menuList, Page firstLevelPage) {
MenuPojo navObj = new MenuPojo();
ValueMap firstLevelPageProperties = firstLevelPage.getProperties();
String pathLink = firstLevelPage.getPath();
navObj.setPageLink(pathLink);
navObj.setPageTitle(firstLevelPage.getTitle());
if (firstLevelPage.listChildren().hasNext()) {
List<MenuPojo> secondLevelItemList = new ArrayList<>();
secondLevelItemList = getFirstLevelItems(firstLevelPage, secondLevelItemList);
navObj.setChildPages(secondLevelItemList);
}
menuList.add(navObj);
}

public List<MenuPojo> getMenuList() {
return menuList;
}
}

 HTL Script on Component:

<sly data-sly-use.menuobj="com.lundbeck.vyeptidtc.core.models.TestModel">
<sly data-sly-list.listObj="${menuobj.menuList}">
<li><a href="${listObj.pageLink}">${listObj.pageTitle}</a></li>
<ul>
<sly data-sly-list.childPageDetails="${listObj.childPages}">
<li><a href="${listObj.pageLink}">${childPageDetails.pageTitle}</a></li>
<ul>
<sly data-sly-list.childPageDetail="${childPageDetails.childPages}">
<li><a href="${listObj.pageLink}">${childPageDetail.pageTitle}</a></li>
<sly>
</ul>
<sly>
</ul>
</sly>
</sly>

 

End User view:

asutosh_jena_0-1622438328204.png

asutosh_jena_1-1622438356061.png

Based on the page,it will retrieve child page and show the links.

 

Thanks!

 

Avatar

Level 2

Hi @Asutosh_Jena_

 

That worked!

Thank you for your reply!!

 

Can I know where should I add my "dialog value"( example - path : /content/retail) in the code. I am trying to select the page path through "path browser" from my component and that respective child pages needs to be displayed on my page.


Avatar

Community Advisor

@Junnu_ravali Please see the below code:

Highlighted are the changes that I have done to read the value from dialog.

 

@Model(adaptables = {SlingHttpServletRequest.class, Resource.class}, defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL)
public class TestModel {

private static final Logger log = LoggerFactory.getLogger(TestModel.class);

@SlingObject
private ResourceResolver resourceResolver;

@ValueMapValue
private String pagePath;
// Here you need to map with the dialog name

private List<MenuPojo> menuList = new ArrayList<>();

@PostConstruct
protected void init() {
log.info("***** :: init :: Start :: ******");
if (StringUtils.isNotBlank(pagePath)) {
Resource pageResource = resourceResolver.getResource(pagePath);
Page currentPage = pageResource != null ? pageResource.adaptTo(Page.class) : null;
menuList = currentPage != null ? getFirstLevelItems(currentPage, menuList) : null;
}
log.info("***** :: init :: End :: *****");
}

private List<MenuPojo> getFirstLevelItems(Page rootPage, List<MenuPojo> menuList) {
Iterator<Page> firstLevelChild = rootPage.listChildren();
while (firstLevelChild.hasNext()) {
Page firstLevelPage = firstLevelChild.next();
if (!firstLevelPage.isHideInNav()) {
getMenuList(menuList, firstLevelPage);
}
}
return menuList;
}

private void getMenuList(List<MenuPojo> menuList, Page firstLevelPage) {
MenuPojo navObj = new MenuPojo();
ValueMap firstLevelPageProperties = firstLevelPage.getProperties();
String pathLink = firstLevelPage.getPath();
navObj.setPageLink(pathLink);
navObj.setPageTitle(firstLevelPage.getTitle());
if (firstLevelPage.listChildren().hasNext()) {
List<MenuPojo> secondLevelItemList = new ArrayList<>();
secondLevelItemList = getFirstLevelItems(firstLevelPage, secondLevelItemList);
navObj.setChildPages(secondLevelItemList);
}
menuList.add(navObj);
}

public List<MenuPojo> getMenuList() {
return menuList;
}
}

  

Avatar

Level 3

Can You please Share the Code of Dailog content.xml?

 

Avatar

Level 3

Hi , I am new to AEM. Its really hard to understand this. Can u share any Github folder where I can see the whole component that helps me to understand clearly. Thanks in advance. Kindly help me