/**
* 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...
]
-
-
Save vwasteels/874f7d08726076bdc580 to your computer and use it in GitHub Desktop.
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
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!
this is worthy of being "LEGEND!". You rock for this recursive solution!