/**
* Get Menu Items From Location
*
* @param $location : location slug given as key in register_nav_menus
*/
function getMenuItemsFromLocation($location) {
$theme_locations = get_nav_menu_locations();
$menu_obj = get_term( $theme_locations[$location], 'nav_menu' );
return is_wp_error($menu_obj) ? [] : getMenuItemsForParent($menu_obj->slug, 0)
}
/**
* Get Menu Items For Parent
*
* @param $menuSlug : menu slug for the CMS entry (not the key in register_nav_menus)
* @param $parentId
* @return array of items formatted as objects with : name / url / children (fetched recursively)
*/
function getMenuItemsForParent($menuSlug, $parentId) {
$args = [
'post_type' => 'nav_menu_item',
'meta_key' => '_menu_item_menu_item_parent',
'meta_value' => $parentId,
'tax_query' => [
[
'taxonomy' => 'nav_menu',
'field' => 'slug',
'terms' => [$menuSlug]
]
],
'order' => 'ASC',
'orderby' => 'menu_order',
'posts_per_page' => -1
];
$tmpItems = query_posts($args);
$items = [];
foreach ( $tmpItems as $tmpItem ) {
$item = new stdClass;
$type = get_post_meta($tmpItem->ID, '_menu_item_type', true);
switch($type):
case 'post_type':
$postId = get_post_meta($tmpItem->ID, '_menu_item_object_id', true);
$post = get_post($postId);
$item->name = $post->post_title;
$item->url = '/'.$post->post_type.'/'.$post->post_name;
break;
case 'custom':
$item->name = $tmpItem->post_title;
$item->url = get_post_meta($tmpItem->ID, '_menu_item_url', true);
// note : this has to be completed with every '_menu_item_type' (could also come from plugin)
endswitch;
$item->children = getMenuItemsForParent($menuSlug, $tmpItem->ID);
$items[] = $item;
}
return $items;
}
/**
* Usage
*/
$menuItems = getMenuItemsFromLocation('footer_menu');
// will return :
[
'name' => 'Menu item 1'
'url' => '/my-post-type/my-url-1'
'children' => [
'name' => 'Menu item 2'
'url' => '/external-custom-link'
'children' => []
],
// etc...
]
Last active
June 28, 2022 13:12
-
-
Save vwasteels/874f7d08726076bdc580 to your computer and use it in GitHub Desktop.
Retrieve menu items hierarchically in Wordpress
The code is awesome and helped me a lot. There's only one bug in there that I nearly spent half a day to fix!
The problem was that the API didn't return all menu items, and the reason was that "posts_per_page => -1" wasn't mentioned as an argument!
@ali-garajian Thanks for noticing this , it's now updated !
taxonomy support:
`
switch( $type):
case 'post_type':
$postId = get_post_meta( $tmpItem->ID, '_menu_item_object_id', true);
$post = get_post( $postId);
$item->name = $post->post_title;
$item->url = get_permalink( $post->ID );
break;
case 'taxonomy':
$tax_id = get_post_meta( $tmpItem->ID, '_menu_item_object_id', true );
$tax_name = get_post_meta( $tmpItem->ID, '_menu_item_object', true );
$term = get_term_by( 'ID', $tax_id, $tax_name );
$item->name = $term->name;
$item->url = get_term_link( $term, $tax_name );
break;
case 'custom':
$item->name = $tmpItem->post_title;
$item->url = get_post_meta( $tmpItem->ID, '_menu_item_url', true);
// note : this has to be completed with every '_menu_item_type' (could also come from plugin)
endswitch;`
@vwasteels Awesome! Thank you so much!
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
You saved me after three days of struggling to get this done, thanks