Jump to content

Processwire Selector - limit levels


Mr. NiceGuy
 Share

Recommended Posts

Hey Guys, 

i building a site where I have many levels of subpages (about 20). The Output gets rendered as tree map. 

Again I'm thrilled how easy it was to build my templates and the site structure, always a pleasure working with PW.

I have one small question. 

I found a way to limit my output to a specific parent via has_parent. 

However Im struggling to implement a function to display only a certain level depth. Say i want Parent X and two levels of his children. 

My only idea was to count the slashes of the path, but that just doesnt feel right to me ;) 

Is there any function of the API that allows for such a selection . 

Just for reference my query is: 

$items=$pages->find("template=t1||t2, limit=200, has_parent=$parent")
Link to comment
Share on other sites

Sure. 

My Sitestructure: (Like this, with ca 100 pages and 15 levels, template t2 only on last level)

Treeroot template=render_tree

-- Treenode 1  template=t1

 ----- Treenode 2  template=t1

----------- Treenode 3      template=t1

-- Treenode 4     template=t1

------ Treenode 5      template=t1

----------- Treenode 6     template=t1

------------ Treenode 7      template=t1

----------------- Treenode 8        template=t2

-- Treenode 9        template=t1

------ Treenode 10      template=t1

------ Treenode 11       template=t1

------------ Treenode 12      template=t1

----------------- Treenode 13     template=t1

---------------------- Treenode 14    template=t2

----------------------- Treenode 15  template=t2

if ($parent) { //If parent set via GET Variable then output only its children
$items= $pages->find("hasParent=$parent, template=t1||t2, limit=1000");
$items->prepend($pages->get($parent));
}else{ //Output all Nodes
$items= $pages->find("template=t1||t2, limit=1000");
};

foreach($items as $item){
echo "[{'$item->id', '$item->parent','$item->title' }],";
}

What I want is not only to specify which parent the pages can have: eg all Childs of treenode 11. 

I also want to limit the level. Eg Display Treenode11 and two levels. (node 12 and 13 are in the page array, node 14 and 15 arent because they are more than 2 levels away)

Link to comment
Share on other sites

Yep, 

I just need an array for every item like this 

[{itemid,parentpageid,text}], 
....

The nested traversal function from the sitemap looks good. Seems easy to implement a counter and restrict the level depth.  I'll have a look at it next week and post my solution. Thanks for the input!

Link to comment
Share on other sites

I was curious of how to achieve this, so I created this function. Should do what you want:

Edit: just realized that this doesn't work. There's is some problem with the loop that I have to solve

Edit2: solved this, I posted a new function some posts bellow https://processwire.com/talk/topic/5876-processwire-selector-limit-levels/?p=58391 no need to remove the likes folks ;) I will leave this one here for public shame :P

// function has 4 parameters
// the only required is the starting parents, all others are optional and default to the displayed values
function myFindPages($parents, $depth = 1, $templates = false, $limit = false) {

    for($i=$depth; $i > 0; $i--) { // for the number of times specied in $depth

        $templates = $templates ?  ', template=' . $templates : '';
        $limit = $limit ? ', limit=' . $limit : '';
        $newParents = ($i < $depth) ? $parents . "|" : ''; // don't include the original parent/s in the final array 
        $allParents = $newParents . wire("pages")->find("parent={$parents}{$templates}{$limit}");
        $parents = myFindPages($allParents, $depth, $templates, $limit); // call the function recursively with the new parents

    }
    return $parents;

}

// call the function

// "parent is home, 2 levels of depths, any template no limit"
$myParent = wire('pages')->get('/');
echo myFindPages($myParent, 2);

// "parents are all children of about, 4 levels of depths, template 'basic' and limit 100 pages"
$myParent = wire('pages')->get('/about/')->children();
echo myFindPages($myParent, 4, 'basic', 100);
  • Like 8
Link to comment
Share on other sites

i identified the problem with the function. Obviously you can't call a recursive function inside a loop like I was doing there, calling a recursive function is already a loop (duh!), so I replaced the for() by a if() and all is good and much simpler.

I also replaced the $template and $limit arguments by a $selector argument (why loose all the flexibility of selectors? duh again!).

// function accepts 3 parameters. $parents is mandatory
function myFindPages($parents, $depth = 1, $selector = '') {
    $allParents = $parents;
    if($depth > 1) {
        $allParents = $parents . '|' . wire('pages')->find("parent={$parents}"); // add new parents to existing
        $parents = myFindPages($allParents, $depth - 1); // call the function recursively with all parents
    }
    $selector = $selector ? ',' . $selector : '';
    return wire('pages')->find("parent={$allParents}{$selector}");
}

// parent is home, 2 levels of depth
$myParent = wire('pages')->get('/');
echo myFindPages($myParent, 2);

// and with selectors
echo myFindPages($myParent, 2, 'template=basic-page, limit=20');
  • Like 4
Link to comment
Share on other sites

Hej Diogo, 

thanks for your efforts ;)  

I tried your last code example and played with it. Seems to work fine with two  and one level but I cant get higher levels to work?

Have you tried 4-6 levels? . 

The iteration is going through all the 5 levels but your algorithm for the parents doesnt work out: All the pages of the respective level are included but two or three times depending on the level depth.

1049|1050|1056 --1049|1050|1056|1050|1051|1056 --1049|1050|1056|1050|1051|1056|1050|1051|1052|1053|1056 --1049|1050|1056|1050|1051|1056|1050|1051|1052|1053|1056|1012|1036|1050|1051|1052|1053|1054|1055|1056

Thats an example of the ouput for 4 levels.   I tried some stuff but im rather a noob at php and have no idea what could be the problem

//Modified code by me 
$allParents = $parents . '|' . wire('pages')->find("parent={$parents}"); // add new parents to existing
        echo $allParents ." --";

with Level depth of 5

Link to comment
Share on other sites

With the MarkupSimpleNavigation you could do it like this:

$opts = array(
    "max_levels" => 3,
    "outer_tpl" => "",
    "inner_tpl" => "",
    "list_tpl" => "",
    "item_tpl" => "{id}|",
    "item_current_tpl" => "{id}|"
    );
$res = $modules->MarkupSimpleNavigation->render($opts);
$res = trim($res, "|");
$allPages = $pages->find("id=$res");
  • Like 3
Link to comment
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
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...