Woocommerce单产品页面:替换加入购物车按钮失效问题排查
问题:WooCommerce单产品页面替换购物车按钮失效
我开发了自定义函数,逻辑为当产品的_shipping_cost元数据为空时,将加入购物车按钮替换为「Prijs op aanvraag(询价)」按钮。该功能在产品归档页运行正常,但在单产品页面无法生效。已查阅WooCommerce钩子文档,仍无法定位问题,请求协助排查单产品页面钩子使用错误。
现有相关代码片段
新按钮函数
function custom_add_price_on_request_button() { global $product; $shipping_cost = get_post_meta($product->get_id(), '_shipping_cost', true); if ($shipping_cost === '') { echo '<a class="button price-on-request-button" href="mailto:info@yourstore.com"><span>Prijs op</span><span>aanvraag</span></a>'; } } add_action('woocommerce_after_shop_loop_item', 'custom_add_price_on_request_button', 11);
移除并添加新按钮函数(单产品页)
function custom_remove_and_add_cart_button_single() { global $product; $shipping_cost = get_post_meta($product->get_id(), '_shipping_cost', true); if ($shipping_cost === '') { // Remove the default add to cart button remove_action('woocommerce_single_product_summary', 'woocommerce_template_single_add_to_cart', 30); remove_action('woocommerce_single_product_summary', 'woocommerce_single_variation_add_to_cart_button', 30); // Add a custom 'Prijs op aanvraag' button add_action('woocommerce_single_product_summary', 'custom_add_price_on_request_button', 35); } } add_action('woocommerce_before_single_product_summary', 'custom_remove_and_add_cart_button_single', 1);
完整代码(归档页生效,单产品页失效)
// Update the price display for products with no shipping cost function custom_price_on_request($price, $product) { $shipping_cost = get_post_meta($product->get_id(), '_shipping_cost', true); if ($shipping_cost === '') { return '<span class="price-on-request">Prijs op aanvraag</span>'; } return $price; } add_filter('woocommerce_get_price_html', 'custom_price_on_request', 10, 2); // Remove the 'Add to Cart' button if there are no shipping costs on archive pages function custom_remove_add_to_cart_button_loop() { global $product; $shipping_cost = get_post_meta($product->get_id(), '_shipping_cost', true); if ($shipping_cost === '') { remove_action('woocommerce_after_shop_loop_item', 'woocommerce_template_loop_add_to_cart', 10); } } add_action('woocommerce_before_shop_loop_item', 'custom_remove_add_to_cart_button_loop', 1); // Verwijder de 'Toevoegen aan winkelwagen' knop op enkele productpagina's en voeg 'Prijs op aanvraag' knop toe function custom_remove_and_add_cart_button_single_product() { global $product; $shipping_cost = get_post_meta($product->get_id(), '_shipping_cost', true); if ($shipping_cost === '') { // Verwijder de standaard 'add to cart' knop remove_action('woocommerce_simple_add_to_cart', 'woocommerce_simple_add_to_cart', 30); remove_action('woocommerce_single_variation', 'woocommerce_single_variation_add_to_cart_button', 20); // Voeg een aangepaste 'Prijs op aanvraag' knop toe add_action('woocommerce_simple_add_to_cart', 'custom_add_price_on_request_button', 30); add_action('woocommerce_single_variation', 'custom_add_price_on_request_button', 20); } } // Filter the add to cart button link verwijderd "toevoegen aan winkelwagen" en behoudt "prijs op aanvraag" function custom_add_to_cart_button($link, $product) { $shipping_cost = get_post_meta($product->get_id(), '_shipping_cost', true); if ($shipping_cost === '') { return ''; // Return an empty string to remove the button } return $link; } add_filter('woocommerce_loop_add_to_cart_link', 'custom_add_to_cart_button', 10, 2); // Add a custom button with 'Prijs op aanvraag' function custom_add_price_on_request_button() { global $product; $shipping_cost = get_post_meta($product->get_id(), '_shipping_cost', true); if ($shipping_cost === '') { echo '<a class="button price-on-request-button" href="mailto:info@yourstore.com"><span>Prijs op</span><span>aanvraag</span></a>'; } } add_action('woocommerce_after_shop_loop_item', 'custom_add_price_on_request_button', 11); // for loop pages // Add custom CSS to make the button style the same function custom_price_on_request_styles() { echo '<style> .price-on-request-button { background-color: #4caf50; /* Same background color */ color: #ffffff; /* Same text color */ border: 1px solid #4caf50; /* Same border */ padding: 10px 30px; /* Same padding */ text-align: center; text-decoration: none; display: inline-block; font-size: 16px; margin: 4px 2px; cursor: pointer; border-radius: 4px; box-shadow: 0 4px #999; /* Added shadow */ } .price-on-request-button span { display: block; } </style>'; } add_action('wp_head', 'custom_price_on_request_styles');
问题排查与修复方案
核心问题分析
- 未绑定单产品页处理函数:
custom_remove_and_add_cart_button_single_product函数没有添加到任何WooCommerce动作钩子中,导致该逻辑完全不会在单产品页执行。 - 钩子优先级与目标不匹配:
- 简单产品的默认添加购物车函数
woocommerce_simple_add_to_cart绑定在woocommerce_single_product_summary钩子上的优先级是30,而非代码中错误指向的woocommerce_simple_add_to_cart钩子。 - 变量产品的移除逻辑位置错误,且未确保在默认按钮渲染前执行移除动作。
- 简单产品的默认添加购物车函数
- 全局
$product可靠性问题:直接依赖全局$product可能在某些场景下未正确初始化,存在空对象风险。
修复后的完整代码
// Update the price display for products with no shipping cost function custom_price_on_request($price, $product) { $shipping_cost = get_post_meta($product->get_id(), '_shipping_cost', true); if ($shipping_cost === '') { return '<span class="price-on-request">Prijs op aanvraag</span>'; } return $price; } add_filter('woocommerce_get_price_html', 'custom_price_on_request', 10, 2); // Remove the 'Add to Cart' button if there are no shipping costs on archive pages function custom_remove_add_to_cart_button_loop() { $product = wc_get_product(get_the_ID()); if (!$product) return; $shipping_cost = get_post_meta($product->get_id(), '_shipping_cost', true); if ($shipping_cost === '') { remove_action('woocommerce_after_shop_loop_item', 'woocommerce_template_loop_add_to_cart', 10); } } add_action('woocommerce_before_shop_loop_item', 'custom_remove_add_to_cart_button_loop', 1); // Handle single product page: replace add to cart button with price on request function custom_handle_single_product_cart_button() { $product = wc_get_product(get_the_ID()); if (!$product) return; $shipping_cost = get_post_meta($product->get_id(), '_shipping_cost', true); if ($shipping_cost === '') { // Remove default add to cart buttons based on product type if ($product->is_type('simple')) { remove_action('woocommerce_single_product_summary', 'woocommerce_template_single_add_to_cart', 30); add_action('woocommerce_single_product_summary', 'custom_add_price_on_request_button', 30); } elseif ($product->is_type('variable')) { remove_action('woocommerce_single_variation', 'woocommerce_single_variation_add_to_cart_button', 20); add_action('woocommerce_single_variation', 'custom_add_price_on_request_button', 20); } } } // Bind to the correct hook - execute before default buttons are rendered add_action('woocommerce_single_product_summary', 'custom_handle_single_product_cart_button', 5); // Filter loop add to cart link function custom_add_to_cart_button($link, $product) { $shipping_cost = get_post_meta($product->get_id(), '_shipping_cost', true); if ($shipping_cost === '') { return ''; } return $link; } add_filter('woocommerce_loop_add_to_cart_link', 'custom_add_to_cart_button', 10, 2); // Add custom price on request button function custom_add_price_on_request_button() { echo '<a class="button price-on-request-button" href="mailto:info@yourstore.com"><span>Prijs op</span><span>aanvraag</span></a>'; } add_action('woocommerce_after_shop_loop_item', 'custom_add_price_on_request_button', 11); // Add custom styles function custom_price_on_request_styles() { echo '<style> .price-on-request-button { background-color: #4caf50; color: #ffffff; border: 1px solid #4caf50; padding: 10px 30px; text-align: center; text-decoration: none; display: inline-block; font-size: 16px; margin: 4px 2px; cursor: pointer; border-radius: 4px; box-shadow: 0 4px #999; } .price-on-request-button span { display: block; } </style>'; } add_action('wp_head', 'custom_price_on_request_styles');
修复要点说明
- 绑定单产品页处理函数:将
custom_handle_single_product_cart_button绑定到woocommerce_single_product_summary钩子(优先级5),确保在默认按钮渲染前执行移除逻辑。 - 按产品类型匹配钩子:针对简单产品和变量产品分别使用正确的默认按钮钩子,保证
remove_action精准生效。 - 优化产品对象获取:使用
wc_get_product(get_the_ID())替代全局$product,避免空对象异常。 - 简化按钮函数逻辑:移除按钮函数内重复的
_shipping_cost判断,外层已做校验,减少冗余代码。
内容的提问来源于stack exchange,提问作者Jason Lommelen
相关产品推荐
相关产品推荐

