I have the following, which successfully inserts a dynamic link as the last top-level menu item of the specified menu:
add_filter( 'wp_nav_menu_items', 'example_last_nav_item', 10, 2 );
function example_last_nav_item( $items, $args ) {
if ( $args - > theme_location == 'account-menu' && is_user_logged_in() ) {
$current_user = wp_get_current_user();
$items .= '<li class="menu-item profile-link"><a href="/' . strtolower( str_replace( ' ', '-', $current_user - > user_login ) ) . '/">Profile</a></li>';
}
return $items;
}
But, how would I access this menu's sub-menu and insert the link as the first item of the sub-menu?
Account Menu Top-level
— DYNAMIC LINK HERE
— Sub-menu Item #2
— Sub-menu Item #3
I have the following, which successfully inserts a dynamic link as the last top-level menu item of the specified menu:
add_filter( 'wp_nav_menu_items', 'example_last_nav_item', 10, 2 );
function example_last_nav_item( $items, $args ) {
if ( $args - > theme_location == 'account-menu' && is_user_logged_in() ) {
$current_user = wp_get_current_user();
$items .= '<li class="menu-item profile-link"><a href="https://example/profile/' . strtolower( str_replace( ' ', '-', $current_user - > user_login ) ) . '/">Profile</a></li>';
}
return $items;
}
But, how would I access this menu's sub-menu and insert the link as the first item of the sub-menu?
Account Menu Top-level
— DYNAMIC LINK HERE
— Sub-menu Item #2
— Sub-menu Item #3
Share Improve this question edited May 2, 2019 at 8:07 Menus asked May 2, 2019 at 7:20 MenusMenus 135 bronze badges 02 Answers
Reset to default 1The following code will go through all items and search the first item that has a parent. If found, new item with the same parent will be inserted as "first child".
add_filter( 'wp_nav_menu_objects', 'se336857_dynamic_submenuitem', 20, 2 );
function se336857_dynamic_submenuitem( $items, $args )
{
if ( !is_user_logged_in() || $args->theme_location != 'account-menu' )
return $items;
$parent = false;
$current_user = wp_get_current_user();
$url = '/profile/' . strtolower(str_replace( ' ', '-', $current_user->user_login ));
$item_profile = [
'title' => __('Profile'),
'url' => home_url( $url ),
'classes' => 'menu-item profile-link',
];
$item_profile = (object)$item_profile;
$item_profile = new WP_Post($item_profile);
$i = -1;
foreach ( $items as $item )
{
++$i;
if ( $item->menu_item_parent == 0 )
continue;
//
// first submenu item
$item_profile->menu_item_parent = $item->menu_item_parent;
$new_items = [ $item_profile ];
array_splice($items, $i, 0, $new_items );
break;
}
return $items;
}
I recommend you to use wp_nav_menu_objects
hook, which allows you to work with menu items as objects, instead of a string. Inside of your if statement you can create as many items as you want.
add_filter( 'wp_nav_menu_objects', 'example_last_nav_item', 10, 2 );
function example_last_nav_item( $items, $args ){
if ( $args->theme_location=='account-menu' && is_user_logged_in() ){
//parent menu item
$parent_item = array(
'title' => __('Profile'),
'menu_item_parent' => 0, //PARENT ELEMENT HAS 0
'ID' => 'profile',
'db_id' => 9999, //MAKE SURE IT's UNIQUE ID
'url' => 'http://google',
'classes' => array( 'custom-menu-item' )
);
//submenu menu item
$submenu_item = array(
'title' => __('Submenu first element'),
'menu_item_parent' => 9999, //FOR SUBMENU ITEM SET PARENT's db_id
'ID' => 'submenu-item',
'db_id' => 99992,
'url' => 'http://google',
'classes' => array( 'custom-menu-item' )
);
$items[] = (object) $parent_item;
$items[] = (object) $submenu_item;
}
return $items;
}
About all item properties you can read here