Template loop syntax for custom array

Silverstripe Version: 4.x

Question:

I would like to loop over this array in my template

array(2) {
  [0]=>
  array(3) {
    ["menu_title"]=>
    string(5) "Segment title 1"
    ["entry_url"]=>
    string(442) "https://example.com"
    ["Apps"]=>
    array(2) {
      [0]=>
      string(15) "App123"
      [1]=>
      string(20) "App321"
    }
  }
  [1]=>
  array(3) {
    ["menu_title"]=>
    string(2) "Segment title 23"
    ["entry_url"]=>
    string(145) "https://another-example.com"
    ["Apps"]=>
    array(3) {
      [0]=>
      string(15) "App765"
      [1]=>
      string(20) "App628"
      [2]=>
      string(41) "App23"
    }
  }
}

Template idea

<% loop $leftMenuItems %>
<ul>
  <% loop $What_goes_here_?? %>
    <li>$menu_title</li>
    <li>$entry_url</li>
    <ul>
      <% loop $Apps %>
        <li>$What_goes_here_??</li>
      <% end_loop %>
    </ul>
  <% end_loop %>
</ul>
<% end_loop %>

I have been looking through the documentation but I haven’t found a solution. Can I use this array for the loop in template? If not, how should the template look like?

Hi,
I guess you suggest ArrayList?
I don’t quite understand how it works.

I tried variations on this, but I don’t know how to push the second level in the list.

$list = new ArrayList();

foreach($myArray as $firstLevel) {
  $list->push($firstLevel);
  foreach($firstLevel as $secondLevel) {
      //   $list->push($secondLevel);
  }
}

.ss

<% loop $list %>
   <li>$menu_title</li>
   <li>$entry_url</li>
     <% loop $Apps%>
      <li>...</li>
    <% end_loop %>
<% end_loop %>

ArrayList provides a way to iterate in template via <% loop %> ... <% end_loop %>. Then you need to provide the tags you can render, and this is provided by any ViewableData based object. For wrapping plain dictionaries you usually use ArrayData. In short you need an ArrayList or ArrayData.

1 Like

It took me a while to get the correct sequence. Basically:

$firstArray = array();

$list1 = new ArrayList();
$i = 0;
foreach($myArray as $firstLevel) {
  $firstArray [$i]['MenuTitle'] = $firstLevel; 
  $secondArray = array();
  $list2 = new ArrayList();
  $k = 0;
  foreach($firstLevel as $secondLevel) {
     $secondArray[$k]['AppName'] = $secondLevel->AppName;
     $list2->push($secondArray[$k]);
     $k++;
  }
  $firstArray [$i]['Apps'] = $list2;
  $list1->push($firstArray[$i]);
  $i++;
}

I did run in a new problem. I’m using this as a custom side menu. I need to add appropriate css classes, so I can expand, collapse menu segments and show selected item. I see that the Navigation menu has some usefull features like $isCurrent

Would it be possible to create a menu from my array? :angel:
This is for frontend only - I don’t require CMS editing.

1 Like

I solved it with $this->URLSegment when I prepare the array for left menu :slight_smile:

1 Like

Just as an aside, in case you haven’t seen it, for SiteTree (aka Page) objects you can use the $Menu template variable to get a menu you can loop through.