I have an html structure that requires customization of the wp_nav_menu
code.
This is the html I need to generate:
<ul class="main-nav"> <li class="item"> <a href="http://example.com/?p=123" class="title">Title</a> <a href="http://example.com/?p=123" class="desc">Description</a> <ul class="sub-menu"> <li class="item"> <a href="http://example.com/?p=123" class="title">Title</a> <a href="http://example.com/?p=123" class="desc">Description</a> </li> </ul> </li> <li class="item"> <a href="http://example.com/?p=123" class="title">Title</a> <a href="http://example.com/?p=123" class="desc">Description</a> </li> </ul>
I am currently using wp_get_nav_menu_items
to get all the items from my menu as an array.
Right now I am able to generate the above html without the sub-menus using the following code:
<?php $menu_name = 'main-nav'; $locations = get_nav_menu_locations() $menu = wp_get_nav_menu_object( $locations[ $menu_name ] ); $menuitems = wp_get_nav_menu_items( $menu->term_id, array( 'order' => 'DESC' ) ); foreach ( $menuitems as $item ): $id = get_post_meta( $item->ID, '_menu_item_object_id', true ); $page = get_page( $id ); $link = get_page_link( $id ); ?> <li class="item"> <a href="<?php echo $link; ?>" class="title"> <?php echo $page->post_title; ?> </a> <a href="<?php echo $link; ?>" class="desc"> <?php echo $page->post_excerpt; ?> </a> </li> <?php endforeach; ?>
I would have generated the menu using the wp_nav_menu
function but I still need the description shown using $page->post_excerpt
.
I've found that there is a property for each item called $item->menu_item_parent
which gives the ID of the parent menu item.
How would I generate the sub-menu in my foreach
loop? Or is there a really simple way using wp_nav_menu
which Google forgot to mention?
To add it on one of the plugin's parent menu, use add_submenu_page() and set the priority of your add_action() to lower i.e, above 10. Then in add_submenu_page(), replace 'plugin-parent-menu-slug' with the slug of the parent menu where you want it to add.
Get it done in simple way! The code snippet is very simple as the following: $menus = get_terms( 'nav_menu' ); $menus = array_combine( wp_list_pluck( $menus, 'term_id' ), wp_list_pluck( $menus, 'name' ) ); print_r( $menus ); // You'll get: // array( 'menu_id' => 'Menu Name' );
Here is an example of what a navigation menu looks like: Thankfully, with the WordPress drag-and-drop menu interface, creating drop-down menus is pretty easy. With that in mind, let’s see a step-by-step guide on how to create a custom menu. To begin, login to your WordPress admin dashboard. Next, go to Appearance >> Menus.
Your WordPress menu is essentially a map of your website. When it’s well designed, customers can use it to browse your site with ease to find exactly what they’re looking for. In this post, we’ll introduce you to WordPress custom menus and walk you through how to create one in four easy steps.
Thankfully, with the WordPress drag-and-drop menu interface, creating drop-down menus is pretty easy. With that in mind, let’s see a step-by-step guide on how to create a custom menu.
However, if you want extra menu functionality added to your site, there are many WordPress Menu plugins such as UberMenu and Superfly to help with that. With these plugins, you get to create large mega menus. You can also add animation effects, images, and videos to your menu.
For anyone who tackles something similar here's my solution:
Here's the code on a github gist for anyone who wants to get in on the copy paste action.
TL;DR Loop over list, drill down if there's a sub menu, close if we reach the end of the sub menu and menu.
Firstly get the menu items as a flat array:
<?php $menu_name = 'main_nav'; $locations = get_nav_menu_locations(); $menu = wp_get_nav_menu_object( $locations[ $menu_name ] ); $menuitems = wp_get_nav_menu_items( $menu->term_id, array( 'order' => 'DESC' ) ); ?>
Then iterate over the array of the menu items:
<nav> <ul class="main-nav"> <?php $count = 0; $submenu = false; foreach( $menuitems as $item ): // set up title and url $title = $item->title; $link = $item->url; // item does not have a parent so menu_item_parent equals 0 (false) if ( !$item->menu_item_parent ): // save this id for later comparison with sub-menu items $parent_id = $item->ID; ?>
Write the first parent item <li>
:
<li class="item"> <a href="<?php echo $link; ?>" class="title"> <?php echo $title; ?> </a> <?php endif; ?>
Check that this items' parent id matches the stored parent id:
<?php if ( $parent_id == $item->menu_item_parent ): ?>
Start sub-menu <ul>
and set $submenu
flag to true for later referance:
<?php if ( !$submenu ): $submenu = true; ?> <ul class="sub-menu"> <?php endif; ?>
Write the sub-menu item:
<li class="item"> <a href="<?php echo $link; ?>" class="title"><?php echo $title; ?></a> </li>
If the next item does not have the same parent id and we have a sub-menu declared then close the sub-menu <ul>
<?php if ( $menuitems[ $count + 1 ]->menu_item_parent != $parent_id && $submenu ): ?> </ul> <?php $submenu = false; endif; ?> <?php endif; ?>
Again, if the next item in the array does not have the same parent id close the <li>
<?php if ( $menuitems[ $count + 1 ]->menu_item_parent != $parent_id ): ?> </li> <?php $submenu = false; endif; ?> <?php $count++; endforeach; ?> </ul> </nav>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With