Jump to content
Sign in to follow this  
Smirftsch

Nav render children only

Recommended Posts

Ok, I am absolutely sure I am missing something simple again, I also read a few more or less similar topics here, yet I couldn't find an answer.

I am using pretty much the original function renderNavTree:

function renderNavTree($items, $maxDepth = 0, $fieldNames = '', $class = 'nav') {

	// if we were given a single Page rather than a group of them, we'll pretend they
	// gave us a group of them (a group/array of 1)
	if($items instanceof Page) $items = array($items);

	// $out is where we store the markup we are creating in this function
	$out = '';

	// cycle through all the items
	foreach($items as $item) {

	    $pageid = wire('page')->id;
		// markup for the list item...
		// if current item is the same as the page being viewed, add a "current" class to it
		$out .= $item->id == wire('page')->id ? "<li class='current'>" : "<li>";

		// markup for the link
		$out .= "<a href='$item->url'>$item->title.$item->id.$pageid</a> ";

		// if there are extra field names specified, render markup for each one in a <div>
		// having a class name the same as the field name
		if($fieldNames) foreach(explode(' ', $fieldNames) as $fieldName) {
			$value = $item->get($fieldName);
			if($value) $out .= " <div class='$fieldName'>$value</div>";
		}

		// if the item has children and we're allowed to output tree navigation (maxDepth)
		// then call this same function again for the item's children 
        if($item->hasChildren() && $maxDepth ) {
			if($class == 'nav') 
                $class = 'nav nav-tree';
            if ($maxDepth > 1 || $item->id == wire('page')->id)
    				$out .= renderNavTree($item->children, $maxDepth-1, $fieldNames, $class);
    			else {
    				foreach($item->children as $childitem) {
    				if ($childitem->id == wire('page')->id)
    					$out .= renderNavTree($item->children, $maxDepth-1, $fieldNames, $class);
    				}
    			}
		}

		// close the list item
		$out .= "</li>";
	}

	// if output was generated above, wrap it in a <ul>
	if($out) $out = "<ul class='$class'>$out</ul>\n";

	// return the markup we generated above
	return $out;
}

 

but I want it only to render the children of the selected page.

Right now the output is like that (having lets say "child2 of child1 selected):

Parent Page

  • Parent
    • child 1
      • child of child 1
      • child2 of child 1
        • child of child2

Fine so far and looks as wanted- BUT - problem appears if having more than one child of parent- it looks like this:

  • Parent
    • child 1
      • child of child 1
      • child2 of child 1
        • child of child2 of child 1
    • child 2
      • child of child2
      • child2 of child2

while I only would want it to render the tree of child 1, not of child2.

Since all are children of Parent (hence same wire('page')->id), I can't distinguish it with id, but what else can I do here?

Ok, I realized that this question is maybe confusing, what I wanted to archive is that only the navtree of the selected page is being rendered, nothing else (well if being absolutely perfect maybe 1 level of rootParent also).

Share this post


Link to post
Share on other sites

for anyone digging such a thing, I mostly solved it now by using "renderNavTree($page.." instead of "renderNavTree($page->rootParent..." in basic-page and using parents() additionally:

 

// cycle through all the items
	foreach($items as $item) {
	
		if (renderParent && $item->id == wire('page')->id)
		{		
			$SkipLevel = 1; // Skip homepageroot 
			foreach($item->parents() as $pitem) 
			{					
				if ($SkipLevel)
				{
					$SkipLevel--;
					continue;	
				}
				$out .="<ul><li class='parentnav'><a href='$pitem->url'>$pitem->title</a></li>";
			}
			$out .="<ul>";
		}
...

only need to make it render 1st level of parentRoot yet 🙂

Share this post


Link to post
Share on other sites

If you haven't discovered it already, the parent() function (https://processwire.com/api/ref/page/parent/) used with a selector can be useful for checking if a page has a particular parent - at any level, not just a parent immediately above it. It returns a null page (id = 0) if the page doesn't have a parent that matches the selector.

For example, if you want to check if a page is a child of a page with id = 123:

if ($page->parent("id=123")->id != 0) {...

With other functions, the has_parent selector can be used for similar purposes.

Share this post


Link to post
Share on other sites

Thanks!

I have to admit I am still a little confused with all options and especially selectors. I tried through a lot of things to get the working of all of it.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...