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

Setting up recursion using Sightly

Avatar

Level 2

Hello experts,

I am working on a navigation component. This component allows you to select which absolute parent to use and will traverse the child pages 1 level deep.

My question to you is, how can I make it so that the user can control how many levels deep the navigation should go? I need to know how to make this less finite.

Below I've included a couple of items for you to look at:

  1. The sightly market of my current configuration
  2. The js file

Thanks a lot for your help.

Matt

HTML

<div data-sly-use.nav="left-nav.js" data-sly-unwrap> <div id="left-nav"> <div class="ln-content"> <ul class="ln-list" data-sly-list.child="${nav.root.listChildren}"> <li class="ln-item" data-sly-test="${!child.isHideInNav}"> <a class="ln-link" href="${child.path}.html"> <span class="ln-link-text">${child.title}</span> <i class="fa fa-angle-right"></i> </a> <!-- Recursion here --> <ul class="ln-submenu" data-sly-test="${child.title == currentPage.title}" data-sly-list.subChildren="${currentPage.listChildren}"> <li class="sm-item"> <a class="sm-link" href="${subChildren.path}.html"> <span class="sm-link-text">${subChildren.title}</span> </a> </li> </ul> <!-- End recursion --> </li> </ul> </div> </div> </div>

 

 

JS

'use strict'; use(function() { var absParent = granite.resource.properties['absParent'] || currentPage.getDepth() - 1; return { root: currentPage.getAbsoluteParent(absParent) }; });
1 Accepted Solution

Avatar

Correct answer by
Employee Advisor

I have made few tweaks in the code to output the markup as you desired. Please download the attached file and rename the extension to zip. 

Thanks,

Kunal 

View solution in original post

6 Replies

Avatar

Employee Advisor

For this use case you can use data-sly-include for recursive calls and set the request attributes(for limit and the current level) before making the nested call. And when you render the links just make sure to check the current level reached with the limit. 

Attached is the sample code which you can test by following the steps. (Rename the file from .txt to .zip after downloading)

  1. Drop the component on a page which has some child nodes. (Ignore the dialog of the component)
  2. By default the component limit is set to show 2 levels deep. You can change the limit by updating the quicklytest.html file. The level should always be 1 and less than the limit. 
<div data-sly-use="${'setAttributes.js' @ limit = 2, level = 1,seed= currentPage}" data-sly-include="links.html" data-sly-unwrap></div> 

For more reference see the following link - 

http://stackoverflow.com/questions/25404863/aem-6-0-additional-parameters-when-using-data-sly-resour...

Avatar

Level 2

Hey kunal23,

 

Thank you for your response. It is very close to what I need. But there is an issue with the structure of the html output in the links.html file. The output that I need should look something like this:

<ul class="ln-list"> <li class="ln-item"> <a class="ln-link" href="#"> <span class="ln-link-text">#</span> </a> <ul class="ln-submenu"> <li class="sm-item"> <a class="sm-link" href="#"> <span class="sm-link-text">#</span> </a> <ul class="ln-submenu"> <li class="sm-item"> <a class="sm-link" href="#"> <span class="sm-link-text">#</span> </a> </li> </ul> </li> </ul> </li> <li class="ln-item"> <a class="ln-link" href="#"> <span class="ln-link-text">#</span> </a> <ul class="ln-submenu"> <li class="sm-item"> <a class="sm-link" href="#"> <span class="sm-link-text">#</span> </a> </li> </ul> </li> </ul>

Could you have a look at that and let me know how to update the file accordingly? Also, in your quicklytest.html file, you have your limit and level attrs switched.

Thanks, Matt

Avatar

Correct answer by
Employee Advisor

I have made few tweaks in the code to output the markup as you desired. Please download the attached file and rename the extension to zip. 

Thanks,

Kunal 

Avatar

Level 2

This is perfect, thank you. Lastly, how can I show which group is currently active?

Lets say I'm at the limit of the recursion, I want to add a class called active to the parent links that got me to the current page. Something like this:

// If my current page is Testing 123, add 'active' class to the two parent links above <ul class="ln-list"> <li class="ln-item"> <a class="ln-link active" href="#"> <span class="ln-link-text">#</span> </a> <ul class="ln-submenu"> <li class="sm-item"> <a class="sm-link active" href="#"> <span class="sm-link-text">#</span> </a> <ul class="ln-submenu"> <li class="sm-item"> <a class="sm-link" href="#"> <span class="sm-link-text">Testing 123</span> </a> </li> </ul> </li> </ul> </li> </ul>

This last request will complete this.

Thanks, Matt

Avatar

Employee Advisor

Create a new use function and pass the navigation link path to it. The function will return the active class name if the navigation link path is a substring of current page path otherwise it will return blank. Then you can use the active class name returned by the function on the respective navigation element. 

Example- 

<dl data-sly-list.subChildren="${currentPage.listChildren}" data-sly-unwrap>
<dl data-sly-use.activeclass="${'active.js' @ path = subChildren.path}" data-sly-unwrap></dl>
<li class="ln-item ${activeclass.name}">