Asked  7 Months ago    Answers:  5   Viewed   39 times

This function adds a tab named "Special Page" into "My Account" tab list:

add_filter( 'woocommerce_account_menu_items' , 'jc_menu_panel_nav' );

function jc_menu_panel_nav() {
    $items = array(
        'dashboard'       => __( 'Dashboard', 'woocommerce' ),
        'orders'          => __( 'Orders', 'woocommerce' ),
        'downloads'       => __( 'Downloads', 'woocommerce' ),
        'edit-address'    => __( 'Addresses', 'woocommerce' ),
        'payment-methods' => __( 'Payment Methods', 'woocommerce' ),
        'edit-account'    => __( 'Account Details', 'woocommerce' ),
        'special-page' => __( 'Special Page', 'woocommerce' ), // My custom tab here
        'customer-logout' => __( 'Logout', 'woocommerce' ),

    return $items;

That results in this:

enter image description here

But the link points to my-account/special-page/, and naturally gives a 404 error.

How I can assign this URL to a file named special-page.php?



Finally I could solve the problem using a snippet provided for the same people of WooCommerce (There are more tips in that page). For anyone interested, paste all the following code in functions.php:

function my_custom_endpoints() {
    add_rewrite_endpoint( 'special-page', EP_ROOT | EP_PAGES );

add_action( 'init', 'my_custom_endpoints' );

function my_custom_query_vars( $vars ) {
    $vars[] = 'special-page';

    return $vars;

add_filter( 'query_vars', 'my_custom_query_vars', 0 );

function my_custom_flush_rewrite_rules() {

add_action( 'wp_loaded', 'my_custom_flush_rewrite_rules' );

I think this way allows more control to order/renaming the menu:

function my_custom_my_account_menu_items( $items ) {
    $items = array(
        'dashboard'         => __( 'Dashboard', 'woocommerce' ),
        'orders'            => __( 'Orders', 'woocommerce' ),
        //'downloads'       => __( 'Downloads', 'woocommerce' ),
        //'edit-address'    => __( 'Addresses', 'woocommerce' ),
        //'payment-methods' => __( 'Payment Methods', 'woocommerce' ),
        'edit-account'      => __( 'Edit Account', 'woocommerce' ),
        'special-page'      => 'Special Page',
        'customer-logout'   => __( 'Logout', 'woocommerce' ),

    return $items;

add_filter( 'woocommerce_account_menu_items', 'my_custom_my_account_menu_items' );

In the following function I included the file to maintain some "order", but it also admits direct code.

Be sure to place the special-page.php file in the myaccount folder.

function my_custom_endpoint_content() {
    include 'woocommerce/myaccount/special-page.php'; 

add_action( 'woocommerce_account_special-page_endpoint', 'my_custom_endpoint_content' );

Important: Once did this, go to Dashboard > Settings > Permalinks and click "Save Settings" in order to flush rewrite rules (thanks @optimiertes)

Source: Tabbed My Account page

Wednesday, March 31, 2021
answered 7 Months ago

Re-save your permalinks.

Any time you have 404s, It's a safe bet to re-save your permalinks. It can't hurt and solves a lot of problems. Presumably, you added the 2nd endpoint after switching themes because once I created some fake templates in the woocommerce folder, your code worked fine for me.


Please don't put this kind of functionality in a theme.
It'd be better in a plugin and then you can flush the permalinks on activation/deactivation.

Wednesday, March 31, 2021
answered 7 Months ago

First in reference below you will find how to override properly woocommerce templates via a theme (avoiding editing the plugin templates).

In your first code snippet, as you can see for woocommerce_single_product_summary hook, you have in order all the different templates that are @hooked in this hook location with do_action() WordPress function:

do_action( 'woocommerce_single_product_summary' ); 

So in your customized code (the 2nd code snippet) you have just replaced the hook, by the hooked template slug (that is NOT a hook) and will NOT work as an entry point action hook. See the references at the bottom of this answer for the list of WooCommerce actions and filters existing hooks

Consequences: All other hooked templates in the commented list code (beginning with @hooked) will be missing if you replace a hook by a template slug.

For the hooks used in the templates see this helpful WooCommerce Visual Hook Guide

Explanations (How to):

HOW TO - Concrete example:

You want to customize woocommerce_template_single_title hooked template in woocommerce_single_product_summary hook.

 THE HOOK NAME:  woocommerce_single_product_summary hook.
 THE TEMPLATES HOOKED (+priority order number)  => corresponding template file name:    
— woocommerce_template_single_title       (5) => single-product/title.php
— woocommerce_template_single_rating     (10) => single-product/rating.php
— woocommerce_template_single_price      (10) => single-product/price.php
— woocommerce_template_single_excerpt    (20) => single-product/short-description.php
— woocommerce_template_single_add_to_cart(30) => single-product/add-to-cart/ (6 files depending on product type)
— woocommerce_template_single_meta       (40) => single-product/review-meta.php
— woocommerce_template_single_sharing -  (50) => single-product/share.php

Then you will need to edit the corresponding woocommerce_single_product_summary hook title.php located in single-product (sub folder)… Finally is not so complicated, once we understand the template structure files and the hooks in that templates.

The priority number, gives the order for the hooked templates: Smaller in first, bigger at the end…

See also: Hooks and their hooked functions execution queue in Wordpress and Woocommerce

Others ways:

You can also use all that existing templates hooks to target very specific changes or customizations, with custom functions located in the function.php file of your active child theme (or theme) or any plugin file too.

Example using add_action() WordPress function:

// define the woocommerce_single_product_summary callback function

function my_custom_action() { 
    echo '<p>This is my custom action function</p>';
add_action( 'woocommerce_single_product_summary', 'my_custom_action', 15 ); 

This function has a priority number of 15 and will display "This is my custom action function" string text, between the product price and the product short description

Optional arguments of this hooked function for this hook:
• The template slug (string).
• The priority (int).


  • Template Structure + Overriding Templates via a Theme
  • Hooks: Action and Filter reference
  • LIST of WooCommerce Action and Filter (Hook Reference)
  • Template Structure + Overriding Templates via a Theme
  • WooCommerce Visual Hook Guide: Single Product Page
Tuesday, June 1, 2021
answered 5 Months ago

This is a working solution for WooCommerce 2.6+ to extend and manipulate the tabbed "My Account" page endpoints (See this reference at the end of this answer), so here it is what you can do to achieve this:

add_action( 'init', 'custom_new_wc_endpoint' );
function custom_new_wc_endpoint() {
    add_rewrite_endpoint( 'edit-order', EP_ROOT | EP_PAGES );

add_filter( 'query_vars', 'custom_query_vars', 0 );
function custom_query_vars( $vars ) {
    $vars[] = 'edit-order';
    return $vars;

add_action( 'after_switch_theme', 'custom_flush_rewrite_rules' );    
function custom_flush_rewrite_rules() {

// The custom template location
add_action( 'woocommerce_account_edit-order_endpoint', 'custom_endpoint_content' );
function custom_endpoint_content() {
    include 'woocommerce/myaccount/edit-order.php'; 

Then you will need, to Insert the new Edit order endpoint into the My Account menu:

add_filter( 'woocommerce_account_menu_items', 'custom_my_account_menu_items' );
function custom_my_account_menu_items( $items ) {
    // Remove the orders menu item.
    $orders_item = $items['orders']; // first we keep it in a variable
    unset( $items['orders'] ); // we unset it then

    // Insert your custom endpoint.
    $items['edit-order'] = __( 'Edit Order', 'woocommerce' );

    // Insert back the logout item.
    $items['orders'] = $orders_item; // we set it back

    return $items;

Important: You will need to flush the rewrite rules (2 ways):

  • Go to the Permalinks options page and re-save the permalinks (thanks to helgatheviking)
  • You can also disable/enable your theme.


  • Tabbed My Account page (WC 2.6+): Creating new endpoints

  • WooCommerce: Assigning an endpoint to a custom template in my account pages

  • How to add a new endpoint in woocommerce (old and incomplete)

Thursday, July 29, 2021
answered 3 Months ago

WooCommerce 3.0+ is a really major update and is much more strict than before. A lot of things have changed and most of custom code used for WooCommerce version 2.6+ will need to be updated.

See the related articles to WooCommerce Development blog

Here in your case you need to update all woocommerce templates in your theme located in your customtheme (folder) > woocommerce (sub folder).

To do that, you will have to replace all listed files from the woocommerce plugin "templates" folder to your theme woocommerce (sub folder):

woocommerce/templates/cart/cart.php                             => customtheme/woocommerce/cart/cart.php
woocommerce/templates/checkout/form-checkout.php                => customtheme/woocommerce/checkout/form-checkout.php
woocommerce/templates/checkout/review-order.php                 => customtheme/woocommerce/checkout/review-order.php
woocommerce/templates/checkout/thankyou.php                     => customtheme/woocommerce/checkout/thankyou.php
woocommerce/templates/content-product.php                       => customtheme/woocommerce/content-product.php  
woocommerce/templates/loop/loop-start.php                       => customtheme/woocommerce/loop/loop-start.php
woocommerce/templates/loop/pagination.php                       => customtheme/woocommerce/loop/pagination.php  
woocommerce/templates/myaccount/form-edit-address.php           => customtheme/woocommerce/myaccount/form-edit-address.php  
woocommerce/templates/single-product/add-to-cart/variable.php   => customtheme/woocommerce/single-product/add-to-cart/variable.php
woocommerce/templates/single-product/product-image.php          => customtheme/woocommerce/single-product/product-image.php
woocommerce/templates/single-product/product-thumbnails.php     => customtheme/woocommerce/single-product/product-thumbnails.php
woocommerce/templates/single-product/short-description.php      => customtheme/woocommerce/single-product/short-description.php
woocommerce/templates/single-product/tabs/description.php       => customtheme/woocommerce/single-product/tabs/description.php
woocommerce/templates/single-product/title.php                  => customtheme/woocommerce/single-product/title.php

But keep a copy of that old template before, as you will need to replace in the new templates all changes that you have made.

See this related documentation: Template Structure + Overriding Templates via a Theme

Saturday, August 7, 2021
answered 3 Months ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :