Jump to:

23486 Posts in 18995 Topics by 2878 members

General Questions

SilverStripe Forums » General Questions » Getting all children and subchildren .. lots of levels deep?

General questions about getting started with SilverStripe that don't fit in any of the categories above.

Moderators: martimiz, Sean, biapar, Willr, Ingo, swaiba, simon_w

Page: 1
Go to End
Author Topic: 2322 Views
  • imagic
    Avatar
    Community Member
    12 Posts

    Getting all children and subchildren .. lots of levels deep? Link to this post

    Hi guys, I've tried doing a search for this, but couldn't really find what I was after.

    Basically I am making a problem solver page, where users are asked questions and depending on the answer,
    they are asked a different question.

    So I've set up a few questions as a pages and subpages.. (the screenshot will help you understand)

    Now that's all fine, but the problem comes when displaying all these children and subchildren on the page.

    They way I'm doing it now is shown below, but this seems like a super code heavy way of doing it.. Just wonder if there was an easier
    way to get all children and subchildren of a page without having to next 10 children controls..

    Can anyone please help? that would be awesome

    <% control Children %>
    <li class="answer"><a href="#" class="q1" rel="$Tag">$Title</a><ul>
    <% control Children %>
           <li>$Title
       <ul>
    <% control Children %>
    <li class="answer"><a href="#" class="q2" rel="$Tag">$Title</a>
    <ul>
    <% control Children %>
    <li>$Title<ul>
          <% control Children %>
    <li class="answer"><a href="#" class="q3" rel="$Tag">$Title</a>
    </li>
    <% end_control %>
    </ul>
    </li>
    <% end_control %>
    </ul>
    </li>
    <% end_control %>
    </ul>
    </li>
    <% end_control %>
    </ul>
    </li>
    <% end_control %>

  • swaiba
    Avatar
    Forum Moderator
    1792 Posts

    Re: Getting all children and subchildren .. lots of levels deep? Link to this post

    hmmm

    My first guess would be to only render the first question (possibly the first answers too) and then, depending on what is clicked, do ajax to add the info in. This would avoid having to render the whole tree first and I'd imagine it would be fairly straight forward. Best of luck...

  • Willr
    Avatar
    Forum Moderator
    5508 Posts

    Re: Getting all children and subchildren .. lots of levels deep? Link to this post

    I think in 2.4 it supports nested includes so you may be able to use recursion like below, otherwise you'll have to use PHP.

    // includes/menu.ss

    <% if Children %>
    <% control Children %>
    <a href="$Link">$MenuTitle</a>
    <% include Menu %>
    <% end_control %>
    <% end_if %>

  • martimiz
    Avatar
    Forum Moderator
    1086 Posts

    Re: Getting all children and subchildren .. lots of levels deep? Link to this post

    I always thought you couldn't use templates recursively, so I tried to see if I missed it somehow. What I get is a timeout once I try to ?flush=1. So probably it wants to over and over add the same template to the manifest? (v2.4.5).

    But I'd be happy if I were wrong...

  • martimiz
    Avatar
    Forum Moderator
    1086 Posts

    Re: Getting all children and subchildren .. lots of levels deep? Link to this post

    OK: recursion is great for getting down the tree. Getting up to rootlevel looks somewhat like using breadcrumbs breadcrumbs, I guess. So maybe something like this:

    // gets parent object into a DataObjectSet, root first
    public function getParentList($maxDepth = 20) {

       $parentList = new DataObjectSet();
       $depth = 1;
       $currentpage = $this;

       while ($currentpage && $currentpage->ParentID && $depth < $maxDepth) {

          $parent = $currentpage->Parent();
          if (isset($parent->ID)) {
             $parentList->insertFirst($parent);
             $currentpage = $parent;
             $depth++;
          }
          else $currentpage = false;
       }
       return $parentList;
    }

    And then (here I put everything in one ul, where only the currentpage has no link, but you could do whatever you want with it):

    <ul>
       <% control ParentList %>
          <li class="parent{$Pos}"><a href="$Link">$Title.XML</a></li>
       <% end_control %>

       <li class="currentPage">(current page) $Title.XML</li>

       <% if Children %>
          <% control Children %>
             <li class="newSelection"><a href="$Link">(possible new selection) $Title.XML</a></li>
          <% end_control %>
       <% end_if %>
    </ul>

    Maybe this will help some? [edit: use insertFirst instead of push]

  • imagic
    Avatar
    Community Member
    12 Posts

    Re: Getting all children and subchildren .. lots of levels deep? Link to this post

    Thanks for your reply guys, I've tried to use Willr's solution, but I get a timeout after doing a ?flush=1

    Any ideas?

    Also thanks martimiz for this bit of code, but I'm trying to go down the tree, rather than up:)

  • martimiz
    Avatar
    Forum Moderator
    1086 Posts

    Re: Getting all children and subchildren .. lots of levels deep? Link to this post

    There's always that bit about getting up or down that tree

    But I'm a bit confused now, since what my example does is get you exactly what your screenshot shows: when you're on page 'is this a thisle?' It shows you:

    - first: all parent pages in the right order (as links)
    - next: the page you're on now (not as link)
    - finally: the childpages you can now choose from (as links)

    As for that time-out - I mentioned that in my first reply...

    [EDIT] ok - i see: not exactly: (if) you really want the entire tree in there - that could use some recursion...

  • Tuckie
    Avatar
    Community Member
    10 Posts

    Re: Getting all children and subchildren .. lots of levels deep? Link to this post

    here's some code used to get all children, but it just returns a flat list, some tweaking should get you what you want:

    function getAllChildren($objectType = null, $parentObject = null, $dataSet = null) {
          if ($parentObject == null) {
             return null;
          }
          
          //for first iteration
          if ($dataSet == null) {
             $dataSet = new DataObjectSet();
          }
          
          $children = $parentObject->Children();
          if (!empty($children)) {
             $dataSet->merge($children);
             foreach ($children as $child) {
                   $dataSet = $this->getAllChildren($objectType, $child, $dataSet);
             }
          }
          
          //remove other object types if objectType has been specified
          if ($objectType) {
             foreach ($dataSet as $object) {
                if ($object->class != $objectType) {
                   $dataSet->remove($object);
                }
             }
          }
          return $dataSet;
       }

    2322 Views
Page: 1
Go to Top

Want to know more about the company that brought you SilverStripe? Then check out SilverStripe.com

Comments on this website? Please give feedback.