/**
* 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
How now list the menus?
Hey, this did not seem to work for taxonomies, post archive, etc. I made https://gist.github.com/kaoskeya/5f31c235c29b307cbda4ca69bdd29fc9
You saved me after three days of struggling to get this done, thanks
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
Broke down my menu to get custom fields and couldn't get it back for 3 levels of sub menu or more...xD
You saved my a** =))
I tweaked it a bit so it should support taxonomies and generally everything else...
... and can get to custom fields a lot easier