简体   繁体   中英

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

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 ?

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

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:

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.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM