Woocommerce: Assigning an Endpoint to a Custom Template in My Account Pages

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

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

WooCommerce - Assign endpoints to multiple custom templates in my-account page

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.

Sidenote

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.

WooCommerce: Adding custom template to customer account pages

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() {
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.

References:

  • 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)

Include custom template file issue in Woocommerce my account page

As the "woocommerce" folder is inside your theme as the function.php file you just need to use:

include 'woocommerce/myaccount/order-a-kit.php';

See this related answer: WooCommerce: Adding custom template to customer account pages

WooCommerce My Account custom endpoint menu item

Updated:

Important: You need first to declare your home page as the My account page in:

WooCommerce settings > Advanced > My account page field.

Use the following:

// Enable endpoint
add_filter( 'woocommerce_get_query_vars', 'myaccount_custom_endpoint_query_var' );
function myaccount_custom_endpoint_query_var( $query_vars ) {
$query_vars['custom-endpoint'] = 'custom-endpoint';

return $query_vars;
}

// Endpoint displayed content
add_action('woocommerce_account_custom-endpoint_endpoint', 'display_custom_endpoint_content' );
function display_custom_endpoint_content(){
echo '<p>' . __("hello") . '</p>';
}

Optionally you can use the following too:

// Add it as my account menu item
add_filter ( 'woocommerce_account_menu_items', 'custom_account_menu_items', 10 );
function custom_account_menu_items( $menu_links ){
$menu_links = array_slice( $menu_links, 0,3 , true )
+ array( 'custom-endpoint' => __('Custom Endpoint') )
+ array_slice( $menu_links, 3, NULL, true );

return $menu_links;
}

// Endpoint page title
add_filter( 'woocommerce_endpoint_custom-endpoint_title', 'set_my_account_custom_endpoint_title', 10, 2 );
function set_my_account_custom_endpoint_title( $title, $endpoint ) {
$title = __( "Custom Endpoint", "woocommerce" );

return $title;
}

Code goes in functions.php file of the active child theme (or active theme).

Edit: The hook woocommerce_get_query_vars is mandatory and replace the function that handle add_rewrite_endpoint(), which is not needed anymore (thanks to @Jitu).

You can flush rewrites rules if needed by going to Wordpress settings > Permalinks and "Save changes".

Tested and works.

wooCommerce custom end points

But they seem to take no effect. Have i put them in the correct directory? Am I soppose to call these classes somewhere else ? I have no idea where I going wrong. Can some please educate me on this matter.

First thing, you created a class, but you never loaded that file or initiated the class. The best way to do this would be in your own plugin.

Second, you have to add the add_rewrite_endpoint() to the install function. Otherwise, it doesn't know to register the new endpoint and your rewrite rules are flushed, but end up exactly the same as they were before... which creates some 404 errors.

Third, recent WooCommerce provides a filter for the endpoint title. And the content doesn't need to reproduce the My Account div or navigation.

Tested and working:

<?php
/**
* Plugin Name: WC Custom Endpoint
* Plugin URI: http://stackoverflow.com/questions/38784599/woocommerce-custom-end-points
* Description: A custom endpoint
* Version: 0.1.0
* Author: Kathy Darling
* Author URI: http://kathyisawesome.com
* Text Domain: wc_custom_endpoint
* Domain Path: /languages
* Requires at least: 4.6.0
* Tested up to: 4.6.0
*
* Copyright: © 2016 Kathy Darling.
* License: GNU General Public License v3.0
* License URI: http://www.gnu.org/licenses/gpl-3.0.html
*/

/**
* The Main WC_Custom_Endpoint class
**/
if ( ! class_exists( 'WC_Custom_Endpoint' ) ) :

class WC_Custom_Endpoint {

const VERSION = '0.1.0';

/**
* Custom endpoint name.
*/
public static $endpoint = 'add_students_details';

/**
* @var WC_Custom_Endpoint - the single instance of the class
* @since 0.1.0
*/
protected static $instance = null;

/**
* Plugin Directory
*
* @since 0.1.0
* @var string $dir
*/
public $dir = '';

/**
* Plugin URL
*
* @since 0.1.0
* @var string $url
*/
public $url = '';

/**
* Main WC_Custom_Endpoint Instance
*
* Ensures only one instance of WC_Custom_Endpoint is loaded or can be loaded.
*
* @static
* @see WC_Custom_Endpoint()
* @return WC_Custom_Endpoint - Main instance
* @since 0.1.0
*/
public static function instance() {
if ( ! isset( self::$instance ) && ! ( self::$instance instanceof WC_Custom_Endpoint ) ) {
self::$instance = new WC_Custom_Endpoint();
}
return self::$instance;
}

public function __construct(){

$this->dir = plugin_dir_path(__FILE__);

$this->url = plugin_dir_url(__FILE__);

// Load translation files
add_action( 'plugins_loaded', array( $this, 'load_plugin_textdomain' ) );

// 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 );

// Insering your new tab/page into the My Account page.
add_filter( 'woocommerce_account_menu_items', array( $this, 'new_menu_items' ) );
add_action( 'woocommerce_endpoint_' . self::$endpoint . '_title', array( $this, 'endpoint_title' ) );
add_action( 'woocommerce_account_' . self::$endpoint . '_endpoint', array( $this, 'endpoint_content' ) );

}

/*-----------------------------------------------------------------------------------*/
/* Localization */
/*-----------------------------------------------------------------------------------*/

/**
* Make the plugin translation ready
*
* @return void
* @since 1.0
*/
public function load_plugin_textdomain() {
load_plugin_textdomain( 'wc-custom-endpoint' , false , dirname( plugin_basename( __FILE__ ) ) . '/languages/' );
}

/*-----------------------------------------------------------------------------------*/
/* Endpoint */
/*-----------------------------------------------------------------------------------*/

/**
* 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;
}

/*-----------------------------------------------------------------------------------*/
/* Display */
/*-----------------------------------------------------------------------------------*/

/**
* Set endpoint title.
*
* @return string
*/
public function endpoint_title() {

return __( 'My Stuff', 'wc_custom_endpoint' );

}

/**
* 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 ] = __( 'My Stuff', 'wc_custom_endpoint' );

// Insert back the logout item.
$items['customer-logout'] = $logout;

return $items;
}

/**
* Endpoint HTML content.
*/
public function endpoint_content() { ?>
<p>Hello World! - custom wc_get_template() can go here</p>

<?php
}

/*-----------------------------------------------------------------------------------*/
/* Activation */
/*-----------------------------------------------------------------------------------*/

/**
* Plugin install action.
* Flush rewrite rules to make our custom endpoint available.
*/
public static function install() {
WC_Custom_Endpoint()->add_endpoints();
flush_rewrite_rules();
}

/**
* Plugin install action.
* Flush rewrite rules to make our custom endpoint available.
*/
public static function uninstall() {
flush_rewrite_rules();
}

} //end class: do not remove or there will be no more guacamole for you

endif; // end class_exists check

/**
* Returns the main instance of WC_Custom_Endpoint to prevent the need to use globals.
*
* @since 1.0
* @return WC_Custom_Endpoint
*/
function WC_Custom_Endpoint() {
return WC_Custom_Endpoint::instance();
}

// Launch the whole plugin
add_action( 'woocommerce_loaded', 'WC_Custom_Endpoint' );

// register activation hook
register_activation_hook( __FILE__, array( 'WC_Custom_Endpoint', 'install' ) );
register_deactivation_hook( __FILE__, array( 'WC_Custom_Endpoint', 'uninstall' ) );


Related Topics



Leave a reply



Submit