iterating over multi dimensional array for a menu iterating over multi dimensional array for a menu codeigniter codeigniter

iterating over multi dimensional array for a menu


You can use recursion to do that job. It takes a bit of getting your head around if you're not familiar with it, but it's very well suited to this kind of problem.

I haven't run this code in PHP, but it will give you an idea.

Basically what happens is that the main menu function checks each item to see if it's an array, and then calls the function again using the sub menu. This will work infinitely deep if required.

<?php  $menu = array(      '/' => 'Home',      '/about' => 'About',      '/foo' => 'boo',      '/contact' => 'contact',      'test' => array(                 'foo' => 'boo'                ),      'test2' => 'foo2'  );?><ul>  <?php showMenu($menu); ?></ul><?php  function showMenu($menu)  {    <?php foreach ($menu_item as $menu =>& $key): ?>          <li><?php echo anchor($menu, $key, $this->uri->slash_segment(1, 'leading') == $menu ? 'class="active"' : '') ?></li>      if(is_array($menu_item))      {        echo "<ul>";        showMenu($menu_item);        echo "</ul>";      }    <?php endforeach ?>  }?>

Hope this helps.


The concept of the other answers is true, but they generate invalid DOM structure, so I decided to fix it.

You can make a helper file and put the drawMenu() function inside. So, you'll be able to call the function as much as you need.

$menu = array(    '/'        => 'Home',    '/about'   => 'About',    '/foo'     => 'boo',    '/contact' => 'contact',    'test'     => array(        'foo' => 'bar',        'baz' => 'qux'    ),    'test2' => 'foo2');function drawMenu($menu){    $CI =& get_instance();    $output = '';    foreach ($menu as $key => $value) {        $output .= "<li>";        if (is_array($value)) {            $output .= anchor('#', $key);            $output .= PHP_EOL."<ul>".PHP_EOL;            $output .= drawMenu($value);            $output .= "</ul>".PHP_EOL."</li>".PHP_EOL;        } else {            $output .= anchor($key, $value, $CI->uri->slash_segment(1, 'leading') == $key ? 'class="active"' : '');            $output .= "</li>".PHP_EOL;        }    }    return $output;}$html = drawMenu($menu);echo '<ul>'. $html .'</ul>';

Side-note: Usage PHP_EOL constant is arbitrary, it just makes generated DOM more readable.


Update:

I improved the drawMenu() functionality, now you can add a URL address for the headers of sub-menus:

$menu = array(    '/'        => 'Home',    '/about'   => 'About',    '/foo'     => 'boo',    '/contact' => 'contact',    'test'     => array(        'foo' => 'bar'    ),    'This is Test2|/url/to/test2' => array(        'baz' => 'qux'    ));

You can add the URL after | separator.

function drawMenu($menu){    $CI =& get_instance();    $output = '';    foreach ($menu as $key => $value) {        $output .= "<li>";        if (is_array($value)) {            if (strpos($key, '|') !== false) {                $param = explode('|', $key);                $output .= anchor($param[1], $param[0]);            } else {                $output .= anchor('#', $key);            }            $output .= PHP_EOL."<ul>".PHP_EOL;            $output .= drawMenu($value);            $output .= "</ul>".PHP_EOL."</li>".PHP_EOL;        } else {            $output .= anchor($key, $value, $CI->uri->slash_segment(1, 'leading') == $key ? 'class="active"' : '');            $output .= "</li>".PHP_EOL;        }    }    return $output;}


You can check if the $key is an array: is_array

Then you can use another foreach to loop through the submenus.