Expand my Community achievements bar.

Dive into Adobe Summit 2024! Explore curated list of AEM sessions & labs, register, connect with experts, ask questions, engage, and share insights. Don't miss the excitement.
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