Home > Blockchain >  How to overwrite a theme function within a custom plugin?
How to overwrite a theme function within a custom plugin?

Time:07-06

To begin with, my problem:

  • I have a WooCommerce error on the W3C Validator platform.
  • I overwrite the file by redirecting the template path of WooCommerce for that specific file.

Problem:

  • The Wordpress Theme that I am currently using is also overwritting the same file as my Custom plugin, as a result the Theme's overwriting cancels out my plugin's overwritting functionality.

CODE:

Here's some of my code:

This is the function I add using the built in wordpress function add_filter() with high priority value of "1" plus the path of the file I am overwritting is... woocommerce/templates/single-product/add-to-cart/variable.php

function wc_locate_template( $template, $template_name, $template_path ) {
    // Check if WooCommerce is present on the website
        if ( empty( $template ) || ! is_callable( 'WC' ) || ( defined( 'WC_TEMPLATE_DEBUG_MODE' ) && WC_TEMPLATE_DEBUG_MODE ) ) {
            return $template;
        }

    // Variables
        $default_path = WC()->plugin_path() . '/templates/';
        $plugin_path  = untrailingslashit( plugin_dir_path( __FILE__ ) ) . '/templates/';
        $template_new = str_replace( $default_path, $plugin_path, $template );

    // Processing
        if (
            false !== strpos( $template, $default_path )
            && file_exists( $template_new )
        ) {
            $template = $template_new;
        }
    // Output
    return $template;
}
add_filter( 'woocommerce_locate_template', 'wc_locate_template', 1, 3 );

Questions:

How can I make sure that my plugin will overwrite the file of in such way or prority so that the theme's overwritting won't overlap it?


Useful links:

Thank you in advance for your time.

CodePudding user response:

priority 1 means your function will be applied first, so any other function attached to the filter with a number higher than 1 will simply overwrite your function.

You need to put highest possible number to make sure your function will be the last one applied.

use PHP_INT_MAX to make your function the last one applied.

add_filter( 'woocommerce_locate_template', 'wc_locate_template', PHP_INT_MAX, 3 );

CodePudding user response:

That's an example on how to override a woocommerce template with a plugin:

add_filter( 'woocommerce_locate_template', 'woo_custom_template', 1, 3 );
   function woo_custom_template( $template, $template_name, $template_path ) {
     global $woocommerce;
     $_template = $template;
     if ( ! $template_path ) 
        
        $template_path = $woocommerce->template_url;
        $plugin_path  = untrailingslashit( plugin_dir_path( __FILE__ ) )  . '/templates/';
 
    // Within passed path within the theme - this is priority
    $template = locate_template(
    array(
      $template_path . $template_name,
      $template_name
    )
   );
 // Processing
   if( ! $template && file_exists( $plugin_path . $template_name ) )
    $template = $plugin_path . $template_name;
 
   if ( ! $template )
    $template = $_template;
   //Output
   return $template;
}

Then you should be able to reach your goal by copying the template you want to override in your plugin folder. Example:

your_plugin/template/WooCommerce/single-product/add-to-cart/variable.php

CodePudding user response:

Hooks and filter are modification which runs based on priority, the highest the priority before its being called will be the its final output

Here's an example Assuming I have this function

function youFree() {
  $imFree = apply_filters('free_filter', 'I am free' );
  return $imFree;
}

then I have all these filters with different priorities

add_filter('free_filter', function() {
  return 'You are not 1';
}, 1);


add_filter('free_filter', function() {
  return 'You are not 10';
}, 10);


add_filter('free_filter', function() {
  return 'You are not 999';
}, 999);

add_action('init', function() {
  add_filter('free_filter', function() {
    return 'You are not init 999';
  }, 999);
});

add_action('wp_footer', function() {
  add_filter('free_filter', function() {
    return 'You are not wp_footer';
  }, 999);
});

Here is the output if you call youFree() on wp_head

add_action('wp_head', function() {
  echo '<pre>', print_r(youFree(), 1), '</pre>';
});
//the output is "You are not init 999" 
//because the add_filter that runs on wp_footer did not take effect 
//as the function is already called way higher specifically in wp_head
//and the final value is last filter being called thats added on init hook with 999 priority

but if you call that youFree() function on wp_footer

add_action('wp_footer', function() {
  echo '<pre>', print_r(youFree(), 1), '</pre>';
}, 20);
//the output is "You are not wp_footer"
//as this was the very last filter before that function is called on wp_footer

So in your situation,

  1. You have to determine at which point the theme do the modification and at which point the value is being called.
  2. Then you need to inject your filter after your theme modifies it and before it was called by woocommerce. Usually, this is as easy as looking at where the theme calls the filter and adding a priority on your filter which is higher than whats on the theme filter.

but if your having a hard at where to inject it your best option is to find it using query monitor

  • Related