WooCommerce: Assigning an endpoint to a custom template in my account pages
Solution 1
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() {
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
Solution 2
First my-account/special-page/
should be myaccount/special-page/
in woocommerce 2.6+.
This solution is Incomplete and I am still working On…
You can use first this hook:
add_action( 'init', 'add_wc_endpoint' );
function add_wc_endpoint(){
add_rewrite_endpoint( 'special-page', EP_ROOT | EP_PAGES );
}
Then filtering wc_get_template
to call your files when the request match your endpoint:
add_filter( 'wc_get_template', 'custom_vc_endpoint', 10, 5 );
function custom_vc_endpoint($located, $template_name, $args, $template_path, $default_path){
if( $template_name == 'myaccount/special-page.php' ){
global $wp_query;
if(isset($wp_query->query['special-page'])){
$located = get_template_directory() . '/woocommerce/myaccount/special-page.php';
}
}
return $located;
}
If you use a child theme, replace get_template_directory()
by get_stylesheet_directory()
… Paste this code in function.php file of your active child theme or theme.
To avoid a 404 error "page not found", you will need to refresh rewrite rules adding to your code:
flush_rewrite_rules();
Update: Finally Dario (the OP) found a working solution. Look at his answer.
References:
- Tabbed My Account page (Official Woocommerce 2.6+): Creating new endpoints
- How to add a new endpoint in woocommerce (old and incomplete)
Solution 3
There is a better way to use a template in your custom page in woocommerce:
function my_custom_endpoint_content() {
wc_get_template( 'myaccount/special-page.php' );
}
add_action( 'woocommerce_account_special-page_endpoint', 'my_custom_endpoint_content' );
this should work without using the wc_get_template filter.
Solution 4
You can add this code to your theme's function.php:
class My_Custom_My_Account_Endpoint {
/**
* Custom endpoint name.
*
* @var string
*/
public static $endpoint = 'special-page';
/**
* Plugin actions.
*/
public function __construct() {
// Actions used to insert a new endpoint in the WordPress.
add_action( 'init', array( $this, 'add_endpoints' ) );
add_filter( 'query_vars', array( $this, 'add_query_vars' ), 0 );
// Change the My Accout page title.
add_filter( 'the_title', array( $this, 'endpoint_title' ) );
// Insering your new tab/page into the My Account page.
add_filter( 'woocommerce_account_menu_items', array( $this, 'new_menu_items' ) );
add_action( 'woocommerce_account_' . self::$endpoint . '_endpoint', array( $this, 'endpoint_content' ) );
}
/**
* Register new endpoint to use inside My Account page.
*
* @see https://developer.wordpress.org/reference/functions/add_rewrite_endpoint/
*/
public function add_endpoints() {
add_rewrite_endpoint( self::$endpoint, EP_ROOT | EP_PAGES );
}
/**
* Add new query var.
*
* @param array $vars
* @return array
*/
public function add_query_vars( $vars ) {
$vars[] = self::$endpoint;
return $vars;
}
/**
* Set endpoint title.
*
* @param string $title
* @return string
*/
public function endpoint_title( $title ) {
global $wp_query;
$is_endpoint = isset( $wp_query->query_vars[ self::$endpoint ] );
if ( $is_endpoint && ! is_admin() && is_main_query() && in_the_loop() && is_account_page() ) {
// New page title.
$title = __( 'Special Page', 'woocommerce' );
remove_filter( 'the_title', array( $this, 'endpoint_title' ) );
}
return $title;
}
/**
* Insert the new endpoint into the My Account menu.
*
* @param array $items
* @return array
*/
public function new_menu_items( $items ) {
// Remove the logout menu item.
$logout = $items['customer-logout'];
unset( $items['customer-logout'] );
// Insert your custom endpoint.
$items[ self::$endpoint ] = __( 'Special Page', 'woocommerce' );
// Insert back the logout item.
$items['customer-logout'] = $logout;
return $items;
}
/**
* Endpoint HTML content.
*/
public function endpoint_content() {
include('woocommerce/myaccount/special-page.php');
}
/**
* Plugin install action.
* Flush rewrite rules to make our custom endpoint available.
*/
public static function install() {
flush_rewrite_rules();
}
}
new My_Custom_My_Account_Endpoint();
// Flush rewrite rules on plugin activation.
register_activation_hook( __FILE__, array( 'My_Custom_My_Account_Endpoint', 'install' ) );
If you don't know where is your theme's function.php:
1.Log in to the WordPress Admin interface
2.In the left sidebar, hover over Appearances, then click Theme Editor
3.In the right sidebar, click functions.php
Dario Ferrer
Updated on July 09, 2022Comments
-
Dario Ferrer almost 2 years
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:
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
? -
Admin almost 8 yearsworked only in localhost, now am testing this online and the clients is forcing me to get this to work today !
-
WebArtisan over 7 yearsthx for solution. Tip: Change "after_switch_theme" hook to any other headers hook "wp_loaded" - for example. And It will works without swithing themes.
-
optimiertes about 7 yearsGo to Dashboard > Settings > Permalinks and click "Save Settings" might be easier for flushing the rewrite rules.
-
Akash Agrawal about 6 yearsHi. I did the same as in the above solution, but I'm getting a page not found 404 error. Is there anything that needs to be updated in wordpress 4?
-
Akash Agrawal about 6 yearsFlushing rewrite rules from Permalinks page didn't help. Though adding flush_rewrite_rules(); in the code did the trick. Thanks for you suggestion
-
LoicTheAztec about 6 years@AkashAgrawal Ok I have added this at the end of this answer. Thanks
-
Akash Agrawal about 6 yearsThis is a my-account endpoint and my-account tab/pages and other tabs along with it are secured. The user has to login to access these pages, is there any procedure by which I can access my custom endpoint without login?
-
LoicTheAztec about 6 years@AkashAgrawal As this endpoints are part of tabbed my account menu, you will not be able to access them without login and I really don't know yet if it's possible todo what you are asking… It should be better to make an accessible clone of the related my account tabs in an other accessible section of your website (that you will display for non logged users)…
-
Ralph Smit about 4 yearsThis might be great code, but not such a great answer. Some extra explanation could be useful. More importantly: Advising to change the theme's functions.php through the Theme Editor is just plain bad practice, especially without mentioning that theme changes shoudl always be made in a child theme.
-
LoicTheAztec over 3 yearsThis answer code is mostly copied from official WooCommerce "Tabbed “My Account” pages in 2.6" documentation and the author is Claudio Sanches (official WooCommerce developper)… It is already linked In the OP answer