How to add submenu or menu in any specific menu option in WordPress programmatically?
Menus in WordPress are highly versatile and can be easily modified to change in your website’s structure. You can edit existing menus, add, or remove menu items, and update the menu hierarchy at any time to reflect any modifications to your website’s content.
In this article, I am going to show you how we can add submenu for any menu item by using “wp_get_nav_menu_items” hook. As, in some scenarios, we might need to modify menus programmatically. Add this hook function in custom plugin or in functions.php file in theme or child theme.
In following code a scenario handled, where a dropdown required to show in a menu option. I added following code in functions.php file in theme’s folders.
function update_nav_menu_items( $items, $menu ) { // only add item to a specific menu. change 'top-menu' as per your required menu->slug if ( $menu->slug == 'top-menu' ) { foreach( $items as $menu_item ) { if( $menu_item->ID == 150 ) { // change menu id as per your required menu item id in which you want to show submenu $args = array( 'post_type' => 'hotels', 'posts_per_page' => -1, 'orderby' => 'post_date', 'order' => 'DESC', 'post_status' => 'publish', ); $_posts = get_posts($args); if(count($_posts) > 0) { $parent_id = $menu_item->ID; foreach($_posts as $_post) { $last_item = end($items); $last_item_order = $last_item->menu_order; $items[] = _update_nav_menu_item( $_post->post_title, get_permalink($_post->ID), $last_item_order +1, $parent_id, 'post', $_post->ID, 'Post'); } } } } } return $items; } add_filter( 'wp_get_nav_menu_items', 'update_nav_menu_items', 20, 2 );
Now following is the helper function _update_nav_menu_item, to created item array.
function _update_nav_menu_item( $title, $url, $order, $parent_id = 0, $object = '', $object_id = '', $type_label = '' ){ $item = new stdClass(); $item->ID = 1000000 + $order + $parent_id; $item->db_id = $item->ID; $item->title = $title; $item->url = $url; $item->menu_order = $order; $item->menu_item_parent = $parent_id; $item->post_type = "nav_menu_item"; $item->type = 'post_type'; $item->type_label = $type_label; $item->object = $object; $item->object_id = $object_id; $item->classes = array(); $item->target = ''; $item->attr_title = ''; $item->description = ''; $item->xfn = ''; $item->status = ''; return $item; }
Note: menu order is important, it must be unique throughout then menu items. So notice, I am getting items last item then getting it’s order then incrementing it to generate order number.
Hope this will help.