Woocommerce - woocommerce_locate_template 的替代品
Woocommerce - Alternative for woocommerce_locate_template
我正在开发一个基于 woocommerce 的插件,作为其中的一部分,我不得不覆盖 woocommerce 的默认模板文件位置。我的意思是我希望从我的插件中加载自定义 woocommerce 模板。
为了做到这一点,我在 woocommerce 中阅读了有关 woocommerce_locate_template 的文章,基于此 article, but I noticed that the same function has been deprecated as per this link。现在我想知道什么是替代功能。
我的全部意图是将默认的 woocommerce 模板加载位置更改为我的插件文件夹。对解决这个问题有帮助吗?
提前致谢。
woocommerce_locate_template 函数已弃用,取而代之的是 wc_locate_template:您可以阅读代码 here。
但是,如果您要查找 过滤器,它仍然是 woocommerce_locate_template 并且需要三个参数:
- $template 即wp核心函数locate_template
的结果
- $template_name 那只是文件名
- $template_path 这是模板的 woocommerce 路径
所以你可以检查 $template_name 是否是你想要拦截的,如果是的话改变路径,像这样
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);
我还没有测试过,对于任何可能的语法错误,我们深表歉意:)
希望对您有所帮助!
-- 更新 1:我忘了分号 :P --
-- 更新二:我搞错了! --
我不得不修改上面的代码以使其正确匹配我需要的模板文件,在我的例子中是 "variable.php"。
$template_name 需要是完整的 woocommerce 根路径,见下文:
查看下面修改后的代码:
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);
如果有人在 2021 年遇到这个问题,值得一提的是过滤器'woocommerce_locate_template'
不会过滤所有模板 woocommerce 文件夹。相反,您需要过滤 2 个其他函数:
add_filter('wc_get_template', 'entex_wc_get_template', 20, 5);
add_filter('wc_get_template_part', 'entex_wc_get_template_part', 20, 3);
例如,根 woocommerce 模板 content-single-product.php
必须用 wc_get_template_part 过滤。
这适用于我们的插件:
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;
}
这是从 PHP class 中撕下并粘贴在这里,希望代码没有被破坏。
如果您只使用几个模板,我们建议注册模板以获得更清晰的性能,并在函数的早期添加如下内容:
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;
我正在开发一个基于 woocommerce 的插件,作为其中的一部分,我不得不覆盖 woocommerce 的默认模板文件位置。我的意思是我希望从我的插件中加载自定义 woocommerce 模板。
为了做到这一点,我在 woocommerce 中阅读了有关 woocommerce_locate_template 的文章,基于此 article, but I noticed that the same function has been deprecated as per this link。现在我想知道什么是替代功能。
我的全部意图是将默认的 woocommerce 模板加载位置更改为我的插件文件夹。对解决这个问题有帮助吗? 提前致谢。
woocommerce_locate_template 函数已弃用,取而代之的是 wc_locate_template:您可以阅读代码 here。
但是,如果您要查找 过滤器,它仍然是 woocommerce_locate_template 并且需要三个参数:
- $template 即wp核心函数locate_template 的结果
- $template_name 那只是文件名
- $template_path 这是模板的 woocommerce 路径
所以你可以检查 $template_name 是否是你想要拦截的,如果是的话改变路径,像这样
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);
我还没有测试过,对于任何可能的语法错误,我们深表歉意:)
希望对您有所帮助!
-- 更新 1:我忘了分号 :P --
-- 更新二:我搞错了! --
我不得不修改上面的代码以使其正确匹配我需要的模板文件,在我的例子中是 "variable.php"。
$template_name 需要是完整的 woocommerce 根路径,见下文:
查看下面修改后的代码:
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);
如果有人在 2021 年遇到这个问题,值得一提的是过滤器'woocommerce_locate_template'
不会过滤所有模板 woocommerce 文件夹。相反,您需要过滤 2 个其他函数:
add_filter('wc_get_template', 'entex_wc_get_template', 20, 5);
add_filter('wc_get_template_part', 'entex_wc_get_template_part', 20, 3);
例如,根 woocommerce 模板 content-single-product.php
必须用 wc_get_template_part 过滤。
这适用于我们的插件:
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;
}
这是从 PHP class 中撕下并粘贴在这里,希望代码没有被破坏。
如果您只使用几个模板,我们建议注册模板以获得更清晰的性能,并在函数的早期添加如下内容:
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;