WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

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.

share|improve this question

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 );
share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

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