krishna89
krishna89

Reputation: 846

Woocommerce - Alternative for woocommerce_locate_template

I am developing a plugin based on woocommerce and as a part of the I had to override the default template file location of woocommerce. I mean I am looking to have a custom woocommerce template loaded from my plugin.

For doing this I read about woocommerce_locate_template in woocommerce based on this article, but I noticed that the same function has been deprecated as per this link. Now I am wondering what could be an alternative function for this.

My whole intention was to change the default woocommerce template loading location to my plugin folder. Any help in resolving this? Thanks in advance.

Upvotes: 8

Views: 5792

Answers (3)

Jonas Lundman
Jonas Lundman

Reputation: 1480

If someone struggle with this as of 2021, worth mention that the filter 'woocommerce_locate_template' does not filter all templates inside woocommerce folder. Instead, You need to filter 2 other functions:

add_filter('wc_get_template', 'entex_wc_get_template', 20, 5);
add_filter('wc_get_template_part', 'entex_wc_get_template_part', 20, 3);

For example, The root woocommerce template content-single-product.php must be filtered with wc_get_template_part.

This is working for our plugin:

function template_base(){
    return untrailingslashit(plugin_dir_path( __FILE__ )) .'/templates/';
}

function entex_wc_get_template($template, $template_name, $args, $template_path, $default_path){

    /* custom theme templates has priority */
    if(strpos($template, '/themes/') !== FALSE) return $template;

    static $cache = array();
    if(isset($cache[$template_name])) return $cache[$template_name];
    
    $plugin_template = wc_locate_template($template_name, WC()->template_path(), $this->template_base());
    if($plugin_template && file_exists($plugin_template)){
        $template = $plugin_template;
        $cache[$template_name] = $template;
    }
    return $template;
}

function entex_wc_get_template_part($template, $slug, $name){
    
    /* custom theme templates has priority */
    if(strpos($template, '/themes/') !== FALSE) return $template;
    
    $template_name = '';
    if($name){
        $template_name = "{$slug}-{$name}.php";
    } else if($slug){
        $template_name = "{$slug}.php";
    }
    if(!$template_name) return $template;
    
    static $cache = array();
    if(isset($cache[$template_name])) return $cache[$template_name];
    
    $plugin_template = template_base().$template_name;
    if($plugin_template && file_exists($plugin_template)){
        $template = $plugin_template;
        $cache[$template_name] = $template;
    }
    return $template;
} 

This is ripped out of the PHP class and pasted here so hopefully the code is not broken.

We recommend to register the templates for cleaner performance, if you only use a few, and add something like this early in the functions:

if(!in_array($template_name, array(
    'archive-product.php',
    'content-product.php',
    'content-product-cat.php',
    'content-single-product.php',
    'content-widget-product.php',
    'checkout/form-checkout.php',
    'checkout/thankyou.php',
    'loop/loop-start.php',
    'loop/loop-end.php'
))) return $template;

Upvotes: 3

pixelkicks
pixelkicks

Reputation: 866

I had to modify the above code in order to get it to correctly match the template file I needed, which in my case was "variable.php".

$template_name needs to be the full woocommerce root path, see below:

See the amended code below:

function intercept_wc_template($template, $template_name, $template_path) {
    if ($template_name == 'single-product/add-to-cart/variable.php') {
        $template = 'wp-content/themes/theme-name/woocommerce/single-product/add-to-cart/variable.php';
    }

    return $template;
}

add_filter('woocommerce_locate_template', 'intercept_wc_template', 20, 3);

Upvotes: 6

Lorenzo Zottar
Lorenzo Zottar

Reputation: 436

woocommerce_locate_template function is deprecated in favor of wc_locate_template: you can read the code here.

However, if you are looking for the filter, it's still woocommerce_locate_template and takes three arguments:

  1. $template that is the result of the wp core function locate_template
  2. $template_name that is only the filename
  3. $template_path that is the woocommerce path for templates

So you can check if the $template_name is what you want to intercept and change the path if true, like this

function intercept_wc_template($template, $template_name, $template_path) {
    if ($template_name == 'that_template.php') {
        $template = 'the/path/of/your/plugin/template.php';
    }
    return $template;
}

add_filter('woocommerce_locate_template', 'intercept_wc_template', 20, 3);

I've not tested it, so sorry for any possible syntax error :)

Hope it helps!

-- Update 1: I forgot a semicolon :P --
-- Update 2: I made a mistake! --

Upvotes: 15

Related Questions