You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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');

问题排查与修复方案

核心问题分析

  1. 未绑定单产品页处理函数:custom_remove_and_add_cart_button_single_product函数没有添加到任何WooCommerce动作钩子中,导致该逻辑完全不会在单产品页执行。
  2. 钩子优先级与目标不匹配:
    • 简单产品的默认添加购物车函数woocommerce_simple_add_to_cart绑定在woocommerce_single_product_summary钩子上的优先级是30,而非代码中错误指向的woocommerce_simple_add_to_cart钩子。
    • 变量产品的移除逻辑位置错误,且未确保在默认按钮渲染前执行移除动作。
  3. 全局$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');

修复要点说明

  1. 绑定单产品页处理函数:将custom_handle_single_product_cart_button绑定到woocommerce_single_product_summary钩子(优先级5),确保在默认按钮渲染前执行移除逻辑。
  2. 按产品类型匹配钩子:针对简单产品和变量产品分别使用正确的默认按钮钩子,保证remove_action精准生效。
  3. 优化产品对象获取:使用wc_get_product(get_the_ID())替代全局$product,避免空对象异常。
  4. 简化按钮函数逻辑:移除按钮函数内重复的_shipping_cost判断,外层已做校验,减少冗余代码。

内容的提问来源于stack exchange,提问作者Jason Lommelen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 10:27:04