php create navigation menu from multidimensional array dynamically
Solution 1
Here is my solution:
<?php
function MakeMenu($items, $level = 0) {
$ret = "";
$indent = str_repeat(" ", $level * 2);
$ret .= sprintf("%s<ul>\n", $indent);
$indent = str_repeat(" ", ++$level * 2);
foreach ($items as $item => $subitems) {
if (!is_numeric($item)) {
$ret .= sprintf("%s<li><a href=''>%s</a>", $indent, $item);
}
if (is_array($subitems)) {
$ret .= "\n";
$ret .= MakeMenu($subitems, $level + 1);
$ret .= $indent;
} else if (strcmp($item, $subitems)){
$ret .= sprintf("%s<li><a href=''>%s</a>", $indent, $subitems);
}
$ret .= sprintf("</li>\n", $indent);
}
$indent = str_repeat(" ", --$level * 2);
$ret .= sprintf("%s</ul>\n", $indent);
return($ret);
}
$menu = Array(
'home' => Array("sub-home1", "sub-home2"),
'about' => Array("sub-about", "about2" => Array("sub-sub-about")),
'staff' => Array("sub-staff1", "sub-staff2"),
'contact' => "contact"
);
print_r($menu);
echo MakeMenu($menu);
?>
Solution 2
Calvin's solution worked for me. Here's the edited version. We can use more nested loops to get sub - sub menu items.
echo '<ul>';
foreach ($menu as $parent) {
echo '<li><a href="#">' . $parent . '</a>';
if (is_array($parent)) {
echo '<ul>';
foreach ($parent as $children) {
echo '<li><a href="#">' . $children . '</a>';
}
echo '</ul>';
}
echo '</li>';
}
echo '</ul>';
Solution 3
I think you can use recursion? Here is some pseudocode, not very familiar with php.
function toNavMenu(array A){
for each element in A{
echo "<li><a href=\"\">" + element.name + "</a>"
if (element is an array){
echo "<ul>"
toNavMenu(element)
echo "</ul>"
}
echo "</li>"
}
}
Solution 4
I would probably slightly adapt the array to be something like the following:
Array(
0 => Array(
'title' => 'Home',
'children' => Array()
),
1 => Array(
'title' => 'Parent',
'children' => Array(
0 => Array(
'title' => 'Sub 1',
'children' => Array(),
),
1 => Array(
'title' => 'Sub 2',
'children' => Array(
0 => Array(
'title' => 'Sub sub 2-1',
'children' => Array(),
),
),
),
)
)
)
With a structure like this you could use recursion to build your menu HTML:
function buildMenu($menuArray)
{
foreach ($menuArray as $node)
{
echo "<li><a href='#'/>" . $node['title'] . "</a>";
if ( ! empty($node['children'])) {
echo "<ul>";
buildMenu($node['children']);
echo "</ul>";
}
echo "</li>";
}
}
klye_g
Updated on June 04, 2022Comments
-
klye_g almost 2 years
I did research on this, and wasn't able to find an exact answer. Most of the questions/answers on here pertaining to this seem to be unfinished. If anyone knows of a finished solution similar to my question, please point me in that direction!
Here is my array:
Array ( ['home'] => Array ( [0] => sub-home1 [1] => sub-home2 ) ['about'] => Array ( [0] => sub-about ['about2'] => Array ( [0] => sub-sub-about ) ) ['staff'] => Array ( [0] => sub-staff1 [1] => sub-staff2 ) ['contact'] => contact )
And here is what I would like to turn it into:
<ul> <li><a href="">home<a/> <ul> <li><a href="">sub-home1</a></li> <li><a href="">sub-home2</a></li> </ul> </li> <li><a href="">about<a/> <ul> <li><a href="">sub-about</a></li> <li><a href="">about2</a> <ul> <li><a href="">sub-sub-about<a/></li> </ul> </li> </ul> </li> <li><a href="">staff<a/> <ul> <li><a href="">sub-staff1</a></li> <li><a href="">sub-staff2</a></li> </ul> </li> <li><a href="">contact<a/></li> </ul>
The array will be dynamically generated, but will have a limit of 3 levels ex: about->about2->sub-sub-about. I tried going off of this question: PHP/MySQL Navigation Menu but they didn't really seem to come to a conclusion? I am familiar with foreach's whiles and for loops but I just can't seem to wrap my head around this one.
EDIT: Enzino, your code works!
-
Matt almost 12 yearsI think what you need here is a recursive function that parses the arrays. Sorry I can't (off the top of my head) give an example, but this is DEFINITELY one case where recursion is necessary.
-
klye_g almost 12 yearsYeah I'm trying to find a good example, not many out there!
-
Matt almost 12 yearsYou want to find a DFS (depth-first search) algorithm and implement it to output the list.
-
-
hoppa almost 12 yearsI fed the array to the function below (modified it first) and it works for me now. Please do note I only did a simple test. The rest of the programming is up to you :)
-
klye_g almost 12 yearsDuh sorry! Had it the other way
-
klye_g almost 12 yearsEnzino, see edit above. Your code is not putting the sub items under their appropriate "parents"
-
Admin almost 12 yearsI've slightly modified the code; please try again and let me know if now it works as expected.
-
klye_g almost 12 yearsThank you very much sir! I was on page 5 of google trying to find a good example. But your solution works. Now I have learned something new!
-
New Alexandria over 11 yearsconsider offering a recursive method
-
Fabien Sa over 10 yearsFor information, to close an anchor it's
</a>
and not<a/>
.