自定义WooCommerce订单状态邮件模板子主题路径调用求助
解决WooCommerce自定义邮件模板子主题路径不生效问题
我来帮你搞定这个子主题邮件模板不生效的问题!你遇到的情况其实挺常见,WooCommerce的模板加载机制有时候需要额外的钩子来引导它找到子主题里的文件,下面给你几个可行的方案,从规范适配到硬编码都有:
方案1:用过滤器强制指定子主题模板路径
WooCommerce提供了woocommerce_locate_template过滤器,我们可以用它来告诉系统优先加载子主题里的目标邮件模板,把下面的代码加到子主题的functions.php里:
add_filter( 'woocommerce_locate_template', 'ms_store_force_custom_email_template', 10, 3 ); function ms_store_force_custom_email_template( $template, $template_name, $template_path ) { // 匹配你的自定义邮件模板文件名 $target_email = 'emails/logistics-eft-paid.php'; if ( $template_name === $target_email ) { // 拼接子主题里的模板完整路径 $child_theme_template = get_stylesheet_directory() . '/woocommerce/' . $target_email; // 如果文件存在,就返回这个路径覆盖默认查找 if ( file_exists( $child_theme_template ) ) { $template = $child_theme_template; } } return $template; }
方案2:硬编码路径直接加载(快速起步方案)
如果你想先快速验证模板内容,直接在触发邮件的逻辑里硬编码子主题路径也是可行的。假设你有一个触发邮件的函数,修改成这样:
function send_logistics_eft_paid_email( $order_id ) { $order = wc_get_order( $order_id ); if ( !$order ) return; // 硬编码子主题模板的绝对路径 $template_file = get_stylesheet_directory() . '/woocommerce/emails/logistics-eft-paid.php'; if ( file_exists( $template_file ) ) { // 捕获模板输出内容 ob_start(); // 把订单对象传给模板,确保模板里能正常调用$order变量 include $template_file; $email_html = ob_get_clean(); // 用WooCommerce自带的邮件类发送 $mailer = WC()->mailer(); $mailer->send( $order->get_billing_email(), '你的邮件主题', // 替换成实际主题 $email_html, $mailer->get_headers(), [] // 如果有附件可以加在这里 ); } }
然后记得在订单状态切换时绑定这个函数:
// 替换成你的自定义状态slug,比如logistics-eft-paid add_action( 'woocommerce_order_status_YOUR_CUSTOM_STATUS_slug_changed', 'trigger_custom_email', 10, 3 ); function trigger_custom_email( $order_id, $old_status, $new_status ) { send_logistics_eft_paid_email( $order_id ); }
必做检查项
- 路径与文件名检查:确保子主题里的路径是
themes/ms-store/woocommerce/emails/logistics-eft-paid.php,文件名大小写完全一致(Linux服务器大小写敏感!) - 清除缓存:不管是网站缓存插件还是服务器缓存,都清一遍,旧模板很可能被缓存住了
- 模板变量验证:模板里要确保能拿到
$order等必要变量,硬编码方案里我已经帮你处理了这个问题
内容的提问来源于stack exchange,提问作者Schalk Joubert
相关产品推荐
相关产品推荐

