本文教你如何将两种 woocommerce 按钮文本逻辑(指定商品显示“去结算”,已加入购物车的商品显示“✓ 已选中”)合并到一个健壮的过滤器中,避免冲突并确保兼容性。
在 WooCommerce 主题或子主题的 functions.php 文件中,若同时启用多个针对 woocommerce_product_single_add_to_cart_text 钩子的过滤器(例如:一个用于特定商品定制文案,另一个用于购物车状态判断),极易因执行顺序、重复全局变量调用或逻辑覆盖导致功能失效甚至白屏。正确的做法是将所有业务逻辑收敛至单个函数中,并解耦关键判断逻辑。
以下是经过优化、生产就绪的完整实现方案:
// ✅ 主过滤器:统一控制单产品页“加入购物车”按钮文案
add_filter( 'woocommerce_product_single_add_to_cart_text', 'woo_custom_cart_button_text' );
function woo_custom_cart_button_text() {
$current_product_id = get_the_ID();
// 定义需特殊处理的指定商品 ID 列表(请按需修改)
$special_products = array( 82, 74 );
// 判断当前商品是否已在购物车中
$is_in_cart = is_product_in_cart( $current_product_id );
// 优先级逻辑:先识别是否为指定商品,再结合购物车状态决策文案
if ( in_array( $current_product_id, $special_products ) ) {
// 对指定商品:无论是否已在购物车,始终显示“去结算”
return __( 'go to checkout', 'woocommerce' );
} elseif ( $is_in_cart ) {
// 对普通商品:若已在购物车,则显示“✓ 已选中”
return __( '✓ already selected', 'woocommerce' );
} else {
// 默认状态:显示标准文案
return __( 'Add to Cart', 'woocommerce' );
}
}
// ? 辅助函数:安全检测商品是否存在于购物车(兼容 WC 3.0+)
function is_product_in_cart( $product_id ) {
// 防御性检查:确保购物车已初始化且非空
if ( ! WC()->cart || ! WC()->cart->get_cart_contents_count() ) {
return false;
}
foreach ( WC()->cart->get_cart() as $cart_item ) {
// 使用 strict comparison(===)匹配 product_id(含变体处理)
if ( $cart_item['product_id'] === $product_id ||
( isset( $cart_item['variation_id'] ) && $cart_item['variation_id'] === $product_id ) )
{
return true;
}
}
return false;
}✅ 关键优化说明:
⚠️ 注意事项:
通过该方案,你既能保留原有“已加入购物车”状态反馈,又能为高优先级商品(如服务类、订阅类)提供直达结算的 UX 引导,实现语义明确、无冲突、易扩展的按钮文案管理体系。