Last active
August 30, 2023 08:45
-
-
Save kongondo/a478e2a9274fc29f5d7cdb93a8166989 to your computer and use it in GitHub Desktop.
Menu Builder getMenuItems() Examples
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Builds a nested list (menu items) of a single menu. | |
* | |
* A recursive function to display nested list of menu items. | |
* | |
* @access private | |
* @param Int $parent ID of menu item. | |
* @param Array $menu Object of menu items to display. | |
* @param Int $first Helper variable to designate first menu item. | |
* @return string $out. | |
* | |
*/ | |
function buildMenuFromObject($parent = 0, $menu, $first = 0) { | |
if(!is_object($menu)) return; | |
$out = ''; | |
$has_child = false; | |
foreach ($menu as $m) { | |
$newtab = $m->newtab ? " target='_blank'" : ''; | |
// if this menu item is a parent; create the sub-items/child-menu-items | |
if ($m->parentID == $parent) {// if this menu item is a parent; create the inner-items/child-menu-items | |
// if this is the first child | |
if ($has_child === false) { | |
$has_child = true;// This is a parent | |
if ($first == 0){ | |
$out .= "<ul class='main-menu cf'>\n"; | |
$first = 1; | |
} | |
else $out .= "\n<ul class='sub-menu'>\n"; | |
} | |
$class = $m->isCurrent ? ' class="current"' : ''; | |
// a menu item | |
$out .= '<li' . $class . '><a href="' . $m->url . '"' . $newtab . '>' . $m->title; | |
// if menu item has children | |
if ($m->isParent) { | |
$out .= '<span class="drop-icon">▼</span>' . | |
'<label title="Toggle Drop-down" class="drop-icon" for="' . wire('sanitizer')->pageName($m->title) . '" onclick>▼</label>' . | |
'</a>' . | |
'<input type="checkbox" id="' . wire('sanitizer')->pageName($m->title) . '">'; | |
} | |
else $out .= '</a>'; | |
// call function again to generate nested list for sub-menu items belonging to this menu item. | |
$out .= buildMenuFromObject($m->id, $menu, $first); | |
$out .= "</li>\n"; | |
}// end if parent | |
}// end foreach | |
if ($has_child === true) $out .= "</ul>\n"; | |
return $out; | |
} | |
################################## | |
/* grab menu items using MarkupMenuBuilder */ | |
$mb = $modules->get('MarkupMenuBuilder');// get Menu Builder | |
/* get menu the menu we want (i.e. a menu created and published using ProcessMenuBuilder) */ | |
// we can pass the menu's Page, page ID, title, name or its menu items string to getMenuItems() | |
#$menu = $pages->get(1299);// pass a Page | |
#$menu = 1299;// pass an ID | |
#$menu = 'main';// pass a name | |
// passing an array | |
#$jsonStr = $pages->get(1299)->menu_items; | |
#$arrayFromJSON = json_decode($jsonStr, true); | |
#$menu = $arrayFromJSON;// pass an array | |
$menu = 'Main';// pass a title | |
/* only these 3 options apply to getMenuItems() */ | |
$options = array('default_title'=> 1, 'default_class'=> 'cool_menu_class', 'current_class_level' => 4); | |
/* grab menu items as a WireArray with Menu objects */ | |
$menuItems = $mb->getMenuItems($menu, 2, $options);// called with options and 2nd argument = 2 {return Menu (WireArray object)} | |
#$menuItems = $mb->getMenuItems($menu);// if calling without without options; 2nd argument defaults to 2 | |
?> | |
<div id="content"> | |
<nav id="mainMenu"> | |
<label for='tm' id='toggle-menu' onclick>Navigation <span class='drop-icon'>▼</span></label> | |
<input id='tm' type='checkbox'> | |
<?php | |
// build menu from array (example 1b only) | |
echo buildMenuFromObject(0, $menuItems); | |
?> | |
</nav> | |
</div> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Builds a nested list (menu items) of a single menu from an Array of menu items. | |
* | |
* A recursive function to display nested list of menu items. | |
* | |
* @access private | |
* @param Int $parent ID of menu item. | |
* @param Array $menu Array of menu items to display. | |
* @param Int $first Helper variable to designate first menu item. | |
* @return string $out. | |
* | |
*/ | |
function buildMenuFromArray($parent = 0, $menu, $first = 0) { | |
if(!is_array($menu)) return; | |
$out = ''; | |
$has_child = false; | |
foreach ($menu as $id => $m) { | |
$parentID = isset($m['parent_id']) ? $m['parent_id'] : 0; | |
$newtab = isset($m['newtab']) && $m['newtab'] ? " target='_blank'" : ''; | |
// if this menu item is a parent; create the sub-items/child-menu-items | |
if ($parentID == $parent) {// if this menu item is a parent; create the inner-items/child-menu-items | |
// if this is the first child | |
if ($has_child === false) { | |
$has_child = true;// This is a parent | |
if ($first == 0){ | |
$out .= "<ul class='main-menu cf'>\n"; | |
$first = 1; | |
} | |
else $out .= "\n<ul class='sub-menu'>\n"; | |
} | |
$class = isset($m['is_current']) && $m['is_current'] ? ' class="current"' : ''; | |
// a menu item | |
$out .= '<li' . $class . '><a href="' . $m['url'] . '"' . $newtab . '>' . $m['title']; | |
// if menu item has children | |
if (isset($m['is_parent']) && $m['is_parent']) { | |
$out .= '<span class="drop-icon">▼</span>' . | |
'<label title="Toggle Drop-down" class="drop-icon" for="' . wire('sanitizer')->pageName($m['title']) . '" onclick>▼</label>' . | |
'</a>' . | |
'<input type="checkbox" id="' . wire('sanitizer')->pageName($m['title']) . '">'; | |
} | |
else $out .= '</a>'; | |
// call function again to generate nested list for sub-menu items belonging to this menu item. | |
$out .= buildMenuFromArray($id, $menu, $first); | |
$out .= "</li>\n"; | |
}// end if parent | |
}// end foreach | |
if ($has_child === true) $out .= "</ul>\n"; | |
return $out; | |
} | |
################################## | |
/* grab menu items using MarkupMenuBuilder */ | |
$mb = $modules->get('MarkupMenuBuilder');// get Menu Builder | |
/* get menu the menu we want (i.e. a menu created and published using ProcessMenuBuilder) */ | |
// we can pass the menu's Page, page ID, title, name or its menu items string to getMenuItems() | |
#$menu = $pages->get(1299);// pass a Page | |
#$menu = 1299;// pass an ID | |
#$menu = 'main';// pass a name | |
// passing an array | |
#$jsonStr = $pages->get(1299)->menu_items; | |
#$arrayFromJSON = json_decode($jsonStr, true); | |
#$menu = $arrayFromJSON;// pass an array | |
$menu = 'Main';// pass a title | |
/* only these 3 options apply to getMenuItems() */ | |
$options = array('default_title' => 0, 'default_class' => 'cool_menu_class', 'current_class_level' => 3); | |
/* grab menu items as Normal PHP Array with Menu items */ | |
// only for example 1b | |
$menuItems = $mb->getMenuItems($menu, 1, $options);// called without options; 2nd argument is 1 so return array | |
#$menuItems = $mb->getMenuItems($menu, 1);// if calling without options; 2nd argument is 1 so return array | |
?> | |
<div id="content"> | |
<nav id="mainMenu"> | |
<label for='tm' id='toggle-menu' onclick>Navigation <span class='drop-icon'>▼</span></label> | |
<input id='tm' type='checkbox'> | |
<?php | |
// build menu from array (example 1b only) | |
echo buildMenuFromArray(0, $menuItems); | |
?> | |
</nav> | |
</div> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Recursively traverse and visit every child item in an array|object of Menu items. | |
* | |
* @param Menu item parent ID $parent to start traversal from. | |
* @param callable $enter function to call upon visiting a child menu item. | |
* @param callable|null $exit function to call after visiting a child menu item (and all of its children). | |
* @param Menu Object|Array $menuItems to traverse. | |
* | |
* @see Modified From mindplay.dk https://processwire.com/talk/topic/110-recursive-navigation/#entry28241 | |
*/ | |
function visit($parent, $enter, $exit=null, $menuItems) { | |
if(!is_object($menuItems)) return; | |
foreach ($menuItems as $m) { | |
if ($m->parentID == $parent) { | |
call_user_func($enter, $m); | |
if ($m->isParent) visit($m->id, $enter, $exit, $menuItems); | |
if ($exit) call_user_func($exit, $m); | |
} | |
} | |
} | |
############################# | |
/* grab menu items using MarkupMenuBuilder */ | |
$mb = $modules->get('MarkupMenuBuilder');// get Menu Builder | |
/* get menu the menu we want (i.e. a menu created and published using ProcessMenuBuilder) */ | |
// we can pass the menu's Page, page ID, title, name or its menu items string to getMenuItems() | |
#$menu = $pages->get(1299);// pass a Page | |
#$menu = 1299;// pass an ID | |
#$menu = 'main';// pass a name | |
// passing an array | |
#$jsonStr = $pages->get(1299)->menu_items; | |
#$arrayFromJSON = json_decode($jsonStr, true); | |
#$menu = $arrayFromJSON;// pass an array | |
$menu = 'Main';// pass a title | |
/* only these 3 options apply to getMenuItems() */ | |
$options = array('default_title'=> 1, 'default_class'=> 'cool_menu_class', 'current_class_level' => 4); | |
/* grab menu items as a WireArray with Menu objects */ | |
#$menuItems = $mb->getMenuItems($menu, 2, $options);// called with options and 2nd argument = 2 {return Menu (WireArray object)} | |
$menuItems = $mb->getMenuItems($menu);// if calling without without options; 2nd argument defaults to 2 | |
?> | |
<div id="content"> | |
<nav id="mainMenu"> | |
<label for='tm' id='toggle-menu' onclick>Navigation <span class='drop-icon'>▼</span></label> | |
<input id='tm' type='checkbox'> | |
<?php | |
echo "<ul class='main-menu cf'>"; | |
visit( | |
0// start from the top items | |
, | |
// function $enter: <li> for a single menu item | |
function($menuItem) { | |
echo '<li><a href="' . $menuItem->url . '">' . $menuItem->title; | |
if ($menuItem->isParent) { | |
echo '<span class="drop-icon">▼</span>' . | |
#'<label title="Toggle Drop-down" class="drop-icon" for="' . wire('sanitizer')->pageName($menuItem->title) . '" onclick>▼</label>' . | |
'<label title="Toggle Drop-down" class="drop-icon" for="sm' . $menuItem->id . '" onclick>▼</label>' . | |
'</a>' . | |
#'<input type="checkbox" id="' . wire('sanitizer')->pageName($menuItem->title) . '"><ul class="sub-menu">' . | |
'<input type="checkbox" id="sm' . $menuItem->id . '"><ul class="sub-menu">'; | |
} | |
else echo '</a>'; | |
}// end function 1 ($enter) | |
, | |
#function $exit: close menu item <li> and sub-menu <ul> tags | |
function($menuItem) { | |
if ($menuItem->isParent) echo '</ul>'; | |
echo '</li>'; | |
}, | |
$menuItems// the menu items (Menu objects in this example) | |
); | |
?> | |
</nav> | |
</div> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Recursively traverse and visit every child item in an array|object of Menu items. | |
* | |
* @param Menu Object|Array $menuItems to traverse. | |
* @param Int $parent ID to start traversal from. | |
* @param Int $depth Depth of sub-menus. | |
* @param Int $first Helper variable to designate first menu item. | |
* @see Modified From @slkwrm https://processwire.com/talk/topic/563-page-level-and-sub-navigation/?p=4490 | |
* @return string $out. | |
*/ | |
function treeMenu($menuItems, $parent, $depth = 1, $first = 0) { | |
if(!is_object($menuItems)) return; | |
$depth -= 1; | |
if ($first == 0){ | |
$out = "\n<ul class='main-menu cf'>"; | |
$first = 1; | |
} | |
else $out = "\n<ul class='sub-menu'>"; | |
foreach($menuItems as $m) { | |
if ($m->parentID == $parent) { | |
$sub = ''; | |
$out .= "\n\t<li>\n\t\t<a href='" . $m->url . "'>" . $m->title; | |
if($m->isParent && $depth > 0 ) { | |
$sub = str_replace("\n", "\n\t\t", treeMenu($menuItems, $m->id, $depth, $first)); | |
$out .= '<span class="drop-icon">▼</span>' . | |
'<label title="Toggle Drop-down" class="drop-icon" for="sm' . $m->id . '" onclick>▼</label>' . | |
'</a>' . | |
'<input type="checkbox" id="sm' . $m->id . '">' . | |
$sub . "\n\t"; | |
} | |
else $out .= "</a>\n\t"; | |
$out .="\n\t</li>"; | |
} | |
}// end foreach | |
$out .= "\n</ul>"; | |
return $out; | |
} | |
############################# | |
/* grab menu items using MarkupMenuBuilder */ | |
$mb = $modules->get('MarkupMenuBuilder');// get Menu Builder | |
/* get menu the menu we want (i.e. a menu created and published using ProcessMenuBuilder) */ | |
// we can pass the menu's Page, page ID, title, name or its menu items string to getMenuItems() | |
#$menu = $pages->get(1299);// pass a Page | |
#$menu = 1299;// pass an ID | |
#$menu = 'main';// pass a name | |
// passing an array | |
#$jsonStr = $pages->get(1299)->menu_items; | |
#$arrayFromJSON = json_decode($jsonStr, true); | |
#$menu = $arrayFromJSON;// pass an array | |
$menu = 'Main';// pass a title | |
/* only these 3 options apply to getMenuItems() */ | |
$options = array('default_title'=> 1, 'default_class'=> 'cool_menu_class', 'current_class_level' => 5); | |
/* grab menu items as a WireArray with Menu objects */ | |
$menuItems = $mb->getMenuItems($menu, 2, $options);// called with options and 2nd argument = 2 {return Menu (WireArray object)} | |
#$menuItems = $mb->getMenuItems($menu);// if calling without without options; 2nd argument defaults to 2 | |
?> | |
<div id="content"> | |
<nav id="mainMenu"> | |
<label for='tm' id='toggle-menu' onclick>Navigation <span class='drop-icon'>▼</span></label> | |
<input id='tm' type='checkbox'> | |
<?php | |
//parameters: menu items, menu item parent ID, depth, first (helper variable; @note: defaults to 0 - only shown here for completeness) | |
echo treeMenu($menuItems, 0, 4, 0); | |
?> | |
</nav> | |
</div> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment