1

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.com/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

0

2 Answers 2

1

The 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;
}
0

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.com',
            '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.com',
            'classes'          => array( 'custom-menu-item' )
        );

        $items[] = (object) $parent_item;
        $items[] = (object) $submenu_item;
    }

    return $items;

}

About all item properties you can read here

3
  • This solution appears to be too static, removing the dynamic element, which is the main focus, inserting one single dynamic link, with the rest being controlled normally under Appearance > Menus.
    – Menus
    Commented May 2, 2019 at 8:17
  • Provide more info about logic of your idea. You asked "how to access submenu" and I gave you an answer.
    – anton
    Commented May 2, 2019 at 10:11
  • The question title is a brief summary, and the specific context is shared in the question body.
    – Menus
    Commented May 2, 2019 at 10:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.