如何为WooCommerce我的账户页面添加带下拉菜单的选项卡并绑定不同模板
Got it, let's turn that single tab into a fully functional dropdown with independent sub-pages. Here's a step-by-step implementation tailored to your needs:
1. Add Rewrite Endpoints for Sub-Menu Items
First, we need to register unique URLs (endpoints) for each sub-page. I'll use example sub-items, but you can adjust the names to fit your loyalty program:
// Register new endpoints for loyalty rewards sub-pages add_action( 'init', 'loyalty_points_my_account_new_endpoints' ); function loyalty_points_my_account_new_endpoints() { // Parent endpoint (optional, can redirect to a sub-page) add_rewrite_endpoint( 'loyalty-points', EP_ROOT | EP_PAGES ); // Sub-menu endpoints (add/remove these as needed) add_rewrite_endpoint( 'loyalty-points-earned', EP_ROOT | EP_PAGES ); add_rewrite_endpoint( 'loyalty-points-redeemed', EP_ROOT | EP_PAGES ); add_rewrite_endpoint( 'loyalty-points-rules', EP_ROOT | EP_PAGES ); }
2. Update Account Menu to Include Dropdown Structure
Next, we'll modify the account menu to add the parent dropdown item and its sub-items. We'll also hide the sub-items from the main menu since they'll live inside the dropdown:
// Add dropdown and sub-items to My Account menu add_filter( 'woocommerce_account_menu_items', 'loyalty_points_my_account_menu_items', 10, 1 ); function loyalty_points_my_account_menu_items( $items ) { // Remove the old single loyalty points item if present unset( $items['loyalty_points'] ); // Add parent dropdown item $items['loyalty-points'] = __( 'Loyalty Rewards', 'text-domain' ); // Add sub-items (adjust labels to match your program) $items['loyalty-points-earned'] = __( 'Points Earned', 'text-domain' ); $items['loyalty-points-redeemed'] = __( 'Points Redeemed', 'text-domain' ); $items['loyalty-points-rules'] = __( 'Earning Rules', 'text-domain' ); // Optional: Reorder to place dropdown after "Orders" $reordered_items = array(); foreach ( $items as $key => $label ) { $reordered_items[$key] = $label; if ( $key === 'orders' ) { // Uncomment below and remove the earlier $items['loyalty-points'] line to insert after Orders // $reordered_items['loyalty-points'] = __( 'Loyalty Rewards', 'text-domain' ); } } return $reordered_items; } // Modify menu HTML to render the dropdown add_filter( 'woocommerce_account_menu_item_html', 'loyalty_points_account_menu_dropdown', 10, 5 ); function loyalty_points_account_menu_dropdown( $item_html, $item, $key, $endpoint, $current_url ) { // Handle parent dropdown item if ( $key === 'loyalty-points' ) { // Define sub-items (match keys from menu items above) $sub_items = array( 'loyalty-points-earned' => __( 'Points Earned', 'text-domain' ), 'loyalty-points-redeemed' => __( 'Points Redeemed', 'text-domain' ), 'loyalty-points-rules' => __( 'Earning Rules', 'text-domain' ), ); // Build sub-menu HTML $sub_menu_html = '<ul class="woocommerce-MyAccount-submenu">'; foreach ( $sub_items as $sub_key => $sub_label ) { $sub_endpoint_url = wc_get_account_endpoint_url( $sub_key ); $is_active = $sub_endpoint_url === $current_url; $sub_menu_html .= sprintf( '<li class="woocommerce-MyAccount-navigation-link%s"> <a href="%s">%s</a> </li>', $is_active ? ' is-active' : '', esc_url( $sub_endpoint_url ), esc_html( $sub_label ) ); } $sub_menu_html .= '</ul>'; // Rewrite parent item to include dropdown toggle and sub-menu $item_html = sprintf( '<li class="woocommerce-MyAccount-navigation-link has-children"> <a href="%s">%s <span class="dropdown-arrow">▼</span></a> %s </li>', esc_url( wc_get_account_endpoint_url( $key ) ), esc_html( $item ), $sub_menu_html ); } // Hide sub-items from main menu (they live in the dropdown) if ( in_array( $key, array( 'loyalty-points-earned', 'loyalty-points-redeemed', 'loyalty-points-rules' ) ) ) { return ''; } return $item_html; }
3. Add Content Handlers for Each Sub-Page
Now, connect each endpoint to its corresponding template file. Make sure you create these template files in your plugin's frontend folder (adjust the path if your setup is different):
// Parent endpoint content (optional: redirect to first sub-page or show a summary) add_action( 'woocommerce_account_loyalty-points_endpoint', 'loyalty_points_endpoint_content' ); function loyalty_points_endpoint_content() { // Redirect to Points Earned page (adjust to your preferred default) wp_redirect( wc_get_account_endpoint_url( 'loyalty-points-earned' ) ); exit; // Alternatively, include a summary template: // include( plugin_dir_path( __FILE__ ) . 'frontend/loyalty-reward-summary.php'); } // Points Earned page content add_action( 'woocommerce_account_loyalty-points-earned_endpoint', 'loyalty_points_earned_endpoint_content' ); function loyalty_points_earned_endpoint_content() { include( plugin_dir_path( __FILE__ ) . 'frontend/loyalty-points-earned.php'); } // Points Redeemed page content add_action( 'woocommerce_account_loyalty-points-redeemed_endpoint', 'loyalty_points_redeemed_endpoint_content' ); function loyalty_points_redeemed_endpoint_content() { include( plugin_dir_path( __FILE__ ) . 'frontend/loyalty-points-redeemed.php'); } // Earning Rules page content add_action( 'woocommerce_account_loyalty-points-rules_endpoint', 'loyalty_points_rules_endpoint_content' ); function loyalty_points_rules_endpoint_content() { include( plugin_dir_path( __FILE__ ) . 'frontend/loyalty-points-rules.php'); }
4. Add CSS for Dropdown Styling
WooCommerce doesn't include default styles for account menu dropdowns, so let's add some basic, theme-friendly CSS:
// Add dropdown styling to My Account page add_action( 'wp_head', 'loyalty_points_account_menu_css' ); function loyalty_points_account_menu_css() { if ( ! is_account_page() ) return; ?> <style> .woocommerce-MyAccount-navigation-link.has-children { position: relative; } .woocommerce-MyAccount-navigation-link.has-children .dropdown-arrow { font-size: 0.8em; margin-left: 6px; } .woocommerce-MyAccount-submenu { display: none; position: absolute; top: 100%; left: 0; background: #ffffff; border: 1px solid #e0e0e0; border-top: none; min-width: 220px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); z-index: 1000; } .woocommerce-MyAccount-navigation-link.has-children:hover .woocommerce-MyAccount-submenu { display: block; } .woocommerce-MyAccount-submenu li { padding: 10px 15px; border-bottom: 1px solid #f0f0f0; } .woocommerce-MyAccount-submenu li:last-child { border-bottom: none; } .woocommerce-MyAccount-submenu li a { color: #333333; text-decoration: none; display: block; } .woocommerce-MyAccount-submenu li.is-active a { color: #007cba; font-weight: 600; } .woocommerce-MyAccount-submenu li:hover a { color: #007cba; } </style> <?php }
Final Step: Flush Rewrite Rules
After adding the new endpoints, you need to flush WordPress rewrite rules to make them work:
- Go to your WordPress Dashboard → Settings → Permalinks
- Click Save Changes (no need to modify any settings, just save)
Customization Tips:
- Adjust the sub-item labels and endpoint names to match your loyalty program's needs
- Tweak the CSS to blend with your theme's design
- If you don't want a parent endpoint, skip registering it and set the first sub-item as the default entry point
内容的提问来源于stack exchange,提问作者sandhya

