user2515606
user2515606

Reputation: 182

Displays Woocommerce My Account Orders instead of Dashboard

I am trying to make it so that the url.com/my-account or the shortcode [woocommerce_my_account] displays the orders instead of the dashboard that displays "Hello User (not user)?".

The only thing I have is for after logging in which redirects to the orders instead of the dashboard, but I then going to the /my-account still displays the dashboard which I don't want.

The closest code I found that does what I want is...

function woocommerce_orders() {
    $user_id = get_current_user_id();
    if ($user_id == 0) {
         return do_shortcode('[woocommerce_my_account]'); 
    }else{
        ob_start();
        wc_get_template( 'myaccount/my-orders.php', array(
            'current_user'  => get_user_by( 'id', $user_id),
            'order_count'   => $order_count
         ) );
        return ob_get_clean();
    }

}
add_shortcode('woocommerce_orders', 'woocommerce_orders');

However, if there are no orders placed then it comes out blank(doesn't display the "No order has been made yet." with shop button) and the my account nav-sidebar doesn't show up. Would I have to make a custom page-template for this to add in the woocommerce account nav-sidebar?

Edit: If I use the orders.php instead of my-orders.php then I am able to get the "No order has been made yet." But still no sidebar-nav

Upvotes: 3

Views: 7687

Answers (5)

businessbloomer
businessbloomer

Reputation: 1122

As of today there's only one workaround to set another My Account tab as default and also preserve the "Dashboard" tab.

Let's say we want to default to the "Downloads" tab. We need to:

  1. replace the “Dashboard” tab content with the “Downloads” tab content
  2. rename the “Dashboard” tab to “Downloads”
  3. hide the original “Downloads” tab as we already have it now
  4. readd the “Dashboard” tab

This is a little complex to paste here so I'll cover point 1 only which is the most difficult one. The rest can be easily found on StackOverflow or this Business Bloomer tutorial as it's basic rename/remove/add My Account tabs work.

As per point 1, we need to overwrite the woocommerce_account_content() function which is responsible to display the "Dashboard" content by default in case we're on the My Account and there are no query vars or there is a non-empty query var called "pagename".

I will therefore remove the WooCommerce function, and add my version instead:

add_action( 'woocommerce_account_content', 'bbloomer_myaccount_replace_dashboard_content', 1 );

function bbloomer_myaccount_replace_dashboard_content() {
    remove_action( 'woocommerce_account_content', 'woocommerce_account_content', 10 );
    add_action( 'woocommerce_account_content', 'bbloomer_account_content' );
}

Now I go define my custom bbloomer_account_content() function, and I basically tell the system that:

  1. if there is no query var or if there is and a query var called "pagename" is not empty, I echo my custom content (the "Downloads" tab content in my case"
  2. otherwise, it means I am on an endpoint URL, and therefore I copy whatever was inside woocommerce_account_content() to return the tab content

Code:

function bbloomer_account_content() {
    global $wp;
    if ( empty( $query_vars = $wp->query_vars ) || ( ! empty( $query_vars ) && ! empty( $query_vars['pagename'] ) ) ) {
        woocommerce_account_downloads();
    } else {
        foreach ( $wp->query_vars as $key => $value ) {
            if ( 'pagename' === $key ) {
                continue;
            }
            if ( has_action( 'woocommerce_account_' . $key . '_endpoint' ) ) {
                do_action( 'woocommerce_account_' . $key . '_endpoint', $value );
                return;
            }
        }
    }
}

In this way, if I go to "example.com/my-account" I will see the "Downloads" tab content; if I switch tab and go to "Dashboard" or "Orders", I will see their original content instead.

Remember that this is only part 1 and therefore additional workaround is needed with parts 2, 3 and 4 to really make it work.

Upvotes: 0

Jordan Enev
Jordan Enev

Reputation: 18644

Using parse_request action:

add_action( 'parse_request', function ( $wp ) {
    // Prevent the redirection, in the case,
    // the user is not logged in (no login, no orders)
    if (!is_user_logged_in()) return false;

    if ( $wp->request === 'my-account' ) {
        wp_redirect( home_url( '/my-account/orders/' ) );
        exit;
    }
}, 10, 1 );

Upvotes: 0

indextwo
indextwo

Reputation: 5905

There's a much easier way: simply catch WordPress's parse_request, check if the request is for my-account (or whatever your account page slug is) and perform a redirect:

function vnm_wc_redirect_account_dashboard( $wp ) {

    if ( !is_admin() ) {
        //  Uncomment the following line if you want to see what the current request is
        //die( $wp->request );

        //  The following will only match if it's the root Account page; all other endpoints will be left alone

        if ( $wp->request === 'my-account' ) {
            wp_redirect( site_url( '/my-account/orders/' ) );
            exit;
        }
    }
}

add_action( 'parse_request', 'vnm_wc_redirect_account_dashboard', 10, 1 );

Upvotes: 4

Ryszard Jędraszyk
Ryszard Jędraszyk

Reputation: 2412

I used code of LoicTheAztec and another complementary snippet, which removes dashboard tab:

// Remove or rename my account page navigation links (removes downloads and dashboard).
add_filter ( 'woocommerce_account_menu_items', 'my_account_menu_order' );
function my_account_menu_order() {
    $menuOrder = array(
        'orders'             => __( 'Orders', 'woocommerce' ),
        // 'downloads'          => __( 'Download', 'woocommerce' ),
        'edit-address'       => __( 'Addresses', 'woocommerce' ),
        'edit-account'        => __( 'Account details', 'woocommerce' ),
        'customer-logout'    => __( 'Logout', 'woocommerce' ),
        // 'dashboard'          => __( 'Dashboard', 'woocommerce' )
    );
    return $menuOrder;
}

I also created a snippet which causes orders tab to be highlighted by default. It's done through adding active class and then CSS opacity: 1 highlights it. Script will show only in account section to avoid bloat where it isn't needed:

// Make orders link highlighted by default in my account section.
add_action('wp_footer', 'taisho_dashboard_orders_highlight');
function taisho_dashboard_orders_highlight() {

    if (!is_account_page()) return; // Account section only

    global $wp;
    $acc_url = get_permalink( get_option( 'woocommerce_myaccount_page_id' ));
    $my_acc =  rtrim( $acc_url , '/' );
    $my_acc = explode( '/', $my_acc );

    ?>
    <script type="text/javascript">
        var dashboard_active = <?php echo $wp->request === end($my_acc) ?>;
        jQuery(document).ready(function($) {
            $('.woocommerce-MyAccount-navigation-link--orders').toggleClass('is-active', dashboard_active);
        });
    </script>

    <?php   
}

Upvotes: 0

LoicTheAztec
LoicTheAztec

Reputation: 253773

You could try the following code (that is not perfect as it removes the access to the dashboard):

add_action( 'woocommerce_account_content', 'remove_dashboard_account_default', 5 );
function remove_dashboard_account_default() {
    remove_action( 'woocommerce_account_content', 'woocommerce_account_content', 10 );
    add_action( 'woocommerce_account_content', 'custom_account_orders', 10 );
}


function custom_account_orders( $current_page ) {
    global $wp;

    if ( ! empty( $wp->query_vars ) ) {
        foreach ( $wp->query_vars as $key => $value ) {
            // Ignore pagename param.
            if ( 'pagename' === $key ) {
                continue;
            }

            if ( has_action( 'woocommerce_account_' . $key . '_endpoint' ) ) {
                do_action( 'woocommerce_account_' . $key . '_endpoint', $value );
                return;
            }
        }
    }

    $current_page    = empty( $current_page ) ? 1 : absint( $current_page );
    $customer_orders = wc_get_orders( apply_filters( 'woocommerce_my_account_my_orders_query', array(
        'customer' => get_current_user_id(),
        'page'     => $current_page,
        'paginate' => true,
    ) ) );

    wc_get_template(
        'myaccount/orders.php',
        array(
            'current_page'    => absint( $current_page ),
            'customer_orders' => $customer_orders,
            'has_orders'      => 0 < $customer_orders->total,
        )
    );
}

Code goes in function.php file of your active child theme (or active theme). Tested and work.

Upvotes: 5

Related Questions