To begin with, my problem:
- I have a
WooCommerce
error on theW3C 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 myCustom plugin
, as a result theTheme's
overwriting cancels out myplugin'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,
- You have to determine at which point the theme do the modification and at which point the value is being called.
- 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