1

I'm adding login/logout links to a nav menu using the following code:

function rp_add_login_logout_links( $items, $args ) {

    $link = wp_loginout( get_permalink( get_option( 'woocommerce_myaccount_page_id' ) ), false );

    if ( 'Shop Menu' == $args->menu ) {
        $items .= '<li id="menu-item-login" class="menu-item menu-item-login">' . $link . '</li>';
    }

    return $items;
}
add_filter( 'wp_nav_menu_items', 'rp_add_login_logout_links', 10, 2 );

Since $items is a string, I can really only easily prepend or append the links to the list. I need this link to appear before a certain menu item in the list, it would end up being the third item from the end. Is there another filter or method I could use to accomplish this?

I tried using strpos to find the nav item I was looking for and manipulate the $items string but couldn't get it to match the menu item HTML.

1 Answer 1

1

Turns out there is a wp_nav_menu_objects filter that allows you to modify the array of nav menu items before they are joined into a string. I was able to accomplish what I needed using the following function:

function wpse121517_add_shop_menu_links( $items, $args ) {

    if ( 'Shop Menu' !== $args->menu )
        return $items;

    // Where to redirect after logging in or out
    $redirect = get_permalink( get_option( 'woocommerce_myaccount_page_id' ) );

    $new_links = array();

    if ( is_user_logged_in() ) {
        $label = 'Logout';
        $link = wp_logout_url( $redirect );

        // Create a nav_menu_item object to hold our link
        // for My Account, only if user is logged-in
        $item = array(
            'title'            => 'Account',
            'menu_item_parent' => 0,
            'ID'               => 'my-account',
            'db_id'            => '',
            'url'              => get_permalink( get_option( 'woocommerce_myaccount_page_id' ) ),
            'classes'          => array( 'menu-item' )
        );

        $new_links[] = (object) $item;  // Add the new menu item to our array
        unset( $item );
    } else {
        $label = 'Login';
        $link = wp_login_url( $redirect );
    }

    // Create a nav_menu_item object to hold our link
    // for login/out
    $item = array(
        'title'            => $label,
        'menu_item_parent' => 0,
        'ID'               => 'loginout',
        'db_id'            => '',
        'url'              => $link,
        'classes'          => array( 'menu-item' )
    );

    $new_links[] = (object) $item; // Add the new menu item to our array
    $index = count( $items ) - 2;  // Insert before the last two items

    // Insert the new links at the appropriate place.
    array_splice( $items, $index, 0, $new_links );

    return $items;
}
add_filter( 'wp_nav_menu_objects', 'wpse121517_add_shop_menu_links', 10, 2 );

Your Answer

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

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