Jump to content

Recommended Posts

Posted

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")
Posted

Maybe proving an example of your structure you are trying to achieve would help clear up your question here I think. 

Posted

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)

Posted

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

Posted

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!

Posted

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
Posted

Looks pretty cool diogo. One small thing - in the recursive call of the function, you are using findPages, instead of myFindPages :)

  • Like 1
Posted

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
Posted

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

Posted

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
Posted

Or with a different parent than "/" root.

...
$parent = $pages->get("/parent/");
$res = $modules->MarkupSimpleNavigation->render($opts, null, $parent);
...
  • Like 1

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
  • Recently Browsing   0 members

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