Mr. NiceGuy Posted March 19, 2014 Share Posted March 19, 2014 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 More sharing options...
RyanJ Posted March 26, 2014 Share Posted March 26, 2014 Maybe proving an example of your structure you are trying to achieve would help clear up your question here I think. Link to comment Share on other sites More sharing options...
Mr. NiceGuy Posted March 28, 2014 Author Share Posted March 28, 2014 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 More sharing options...
Soma Posted March 28, 2014 Share Posted March 28, 2014 It's not possible (as far as I know) to limit the levels via a find selector. If it's for listing output you have to write nested traversal function (see sitemap code in default profile) or use a module like MarkupSimpleNavigation Link to comment Share on other sites More sharing options...
Mr. NiceGuy Posted March 28, 2014 Author Share Posted March 28, 2014 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 More sharing options...
diogo Posted March 28, 2014 Share Posted March 28, 2014 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 // 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); 8 Link to comment Share on other sites More sharing options...
adrian Posted March 28, 2014 Share Posted March 28, 2014 Looks pretty cool diogo. One small thing - in the recursive call of the function, you are using findPages, instead of myFindPages 1 Link to comment Share on other sites More sharing options...
diogo Posted March 28, 2014 Share Posted March 28, 2014 Thanks Adrian. Corrected. Link to comment Share on other sites More sharing options...
diogo Posted March 28, 2014 Share Posted March 28, 2014 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'); 4 Link to comment Share on other sites More sharing options...
Mr. NiceGuy Posted March 29, 2014 Author Share Posted March 29, 2014 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 More sharing options...
Soma Posted March 29, 2014 Share Posted March 29, 2014 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"); 3 Link to comment Share on other sites More sharing options...
Soma Posted March 29, 2014 Share Posted March 29, 2014 Or with a different parent than "/" root. ... $parent = $pages->get("/parent/"); $res = $modules->MarkupSimpleNavigation->render($opts, null, $parent); ... 1 Link to comment Share on other sites More sharing options...
Mr. NiceGuy Posted March 29, 2014 Author Share Posted March 29, 2014 Superb, Works great! Thanks to everyone taking the time Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now