Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Render Menu
<?php
/**
* Render_Menu
* -----------------
* Render a menu using simple, semantic HTML
*
* Usage: new Render_Menu(@name)
*
* @name (string) name of the menu ("main-navigation")
*
* Output:
* <ul>
* <li><a href="/home">Home</a>
* <li><a href="/mission">Our Mission</a>
* <li class="has-self"><a href="/team">Our Team</a>
* <ul class="has-self">
* <li><a href="/team/jonathan">Jonathan</a>
* <li class="self"><a href="/team/christina">Christina</a>
* </ul>
* </ul>
*/
class Render_Menu {
function __construct($menu_name) {
// get the id of the current document
$currentId = get_queried_object_id();
if (($locations = get_nav_menu_locations()) && isset($locations[$menu_name])) {
// get the menu
$menu = wp_get_nav_menu_object($locations[$menu_name]);
// get all of the menu items
$menu_items = wp_get_nav_menu_items($menu->term_id, 0);
// create an empty array
$menu_array = array();
// loop through all of the menu items
foreach ((array) $menu_items as $key => $menu_item) {
// if the menu item is top level
if ($menu_item->menu_item_parent == 0) {
$menu_array[$menu_item->ID] = $menu_item;
} else {
// if the menu item's parent does not yet have an array for children
if (!isset($menu_array[$menu_item->menu_item_parent]->children)) {
$menu_array[$menu_item->menu_item_parent]->children = array();
}
// push the menu item to the parent's array for children
array_push($menu_array[$menu_item->menu_item_parent]->children, $menu_item);
}
// assign whether the menu item represents the current document
$menu_item->is_self = $menu_item->object_id == $currentId;
// if the menu item represents the current document
if ($menu_item->is_self) {
// while menu_item exists
while ($menu_item) {
// assign the menu as either representing or containing the representative of the current document
$menu_item->has_self = true;
// assign menu_item as its parent
$menu_item = $menu_array[$menu_item->menu_item_parent];
}
}
}
print($this->render($menu_array));
}
}
function render($menu_items, $has_self = false) {
$buffer = '<ul'.($has_self ? ' class="has-self"' : '').'>';
foreach ((array) $menu_items as $menu_item) {
$buffer.= '<li'.($menu_item->is_self ? ' class="self"' : ($menu_item->has_self ? ' class="has-self"' : '')).'>';
$buffer.= '<a href="'.$menu_item->url.'">'.$menu_item->title.'</a>';
$buffer.= $menu_item->children ? $this->render($menu_item->children, $menu_item->has_self) : '';
}
$buffer.='</ul>';
return $buffer;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment