【问题标题】:Customize Cart Totals and Checkout Totals Text based on product categories根据产品类别自定义购物车总计和结帐总计文本
【发布时间】:2019-08-14 00:29:48
【问题描述】:

我想根据产品类别(或其他一些逻辑)自定义购物车和结帐订单汇总表中的文本。例如,对于“总计”文本(参见图片) - 如果购物车包含名为“杂货”的类别中的产品,那么我希望订单摘要中的文本显示为“总计估计”文本(参见图片以下)。如果购物车不包含任何杂货,那么我想要默认文本。

我找到了一个让我开始的解决方案,但需要更多帮助。

根据link,我将文件从 woocommerce/templates/ 复制到我的子主题中,并将其命名为 woocommerce/。例如,从review_order.php 文件中,我需要编辑下面的部分。

<th><?php _e( 'Total', 'woocommerce' ); ?></th>

但是,我不能只用硬编码字符串替换它,因为我的文本取决于逻辑。所以,我需要用函数替换字符串。

我想在下面做这样的事情:

<th><?php _e( get_my_custom_text(), 'woocommerce' ); ?></th>

,其中get_my_custom_text() 根据某些逻辑返回适当的文本,例如购物车中的物品类别。

  1. 我需要将包含函数get_my_custom_text() 的文件放在哪里,以便review_order.php 可以看到该函数?
  2. 这是实现我的目标的最佳方式吗?

更新: 在下面的讨论之后,我将添加我的 get_custom_text() 代码。我试图通过两种方式解决这个问题:第一种是woocommerce files 方式,第二种是下面建议使用add_filter( 'gettext', 'my_text_strings', 20, 3 ) 钩子。在这两种情况下,get_my_custom_text() 在检查购物车时似乎都不起作用。请参阅下面使用钩子方法的代码。我在 get_cart_contents_count() 上得到了一个错误,并且还得到了白屏死机

[23-Mar-2019 11:14:13 UTC] PHP Fatal error: Uncaught Error: Call to a member function get_cart_contents_count() on null in /opt/wordpress/htdocs/wp-content/themes/divi-child/functions.php:446

还得到: [23-Mar-2019 11:16:05 UTC] PHP Fatal error: Allowed memory size of 536870912 bytes exhausted (tried to allocate 20480 bytes) in /opt/wordpress/htdocs/wp-includes/class-wp-hook.php on line 279

   add_filter( 'gettext', 'my_text_strings', 20, 3 );
    function my_text_strings( $translated_text, $text, $domain ) {

            switch ( $translated_text ) {
               case 'Total' :
                    $translated_text = __( get_my_custom_text(), 'woocommerce' );
                    break;
             }

                return $translated_text;
    }

        function get_my_custom_text()
        {
            $is_groceries = has_groceries();
            if($is_groceries){
                return 'Total Estimate';
            }else{
                return 'Total';
            }
        }

        //checks whether cart has any items in the "groceries" category
        function has_groceries()
        {

            if( !$cart = WC()->cart ){
                return false;
            }

          //not sure how error gets here if cart is null     
          write_log('cart contents: '. WC()->cart->get_cart_contents_count());

            $categories = array(  
                '181' => 'groceries' 
              );

            foreach( $cart->get_cart() as $cart_item ){
                foreach ($categories as $category => $value) {
                    if( has_term( $category, 'product_cat', $cart_item['product_id']) ){
                        return true;
                     }
                  }
            }
        return false;
        }

【问题讨论】:

  • 实际上,我最初的问题是,如果我要使用复制 woocommerce 文件的方法,我将放置 get_my_custom_text() 的位置。但随着讨论的继续,需要更新问题

标签: php wordpress woocommerce


【解决方案1】:

您为什么要尝试进入日志,购物车项目计数(在您的函数中)。这不是真的有用。

我已经简化并重新访问了您的代码,并且我没有在最后一个函数中使用get_my_custom_text(),因为使用has_groceries() 反而更简单有效:

// Custom function based on has_groceries() conditional function that returns a string
function get_my_custom_text() {
    return has_groceries() ? 'Total Estimate' : 'Total';
}

// Custom conditional function checking for a specific product category in cart items
function has_groceries() {
    if( ! WC()->cart->is_empty() ){
        // Loop through cart items
        foreach( WC()->cart->get_cart() as $cart_item ){
            if( has_term( array('groceries'), 'product_cat', $cart_item['product_id']) )
                return true;
        }
    }
    return false;
}

// Change 'Total' text conditionally
add_filter( 'gettext', 'changing_total_text_string', 10, 3 );
function changing_total_text_string( $translated_text, $text, $domain ) {
    // Only in cart and checkout pages
    if ( ( ( is_checkout() && ! is_wc_endpoint_url() ) || is_cart() )
    && $text === 'Total' && $domain === 'woocommerce' && has_groceries() ) {
        $translated_text = __('Total Estimate');
    }
    return $translated_text;
}

代码在您的活动子主题(或活动主题)的 function.php 文件中。经过测试并且可以工作。

这样可以避免“Total”文本替换的无限循环。

【讨论】:

  • 1/ 关于日志的问题 - 这是从调试日志中遗留下来的 2/ 我发现了问题,但我无法解释原因。这条线是罪魁祸首,我不知道 __(string, string) 函数的作用,以及 'woocommerce' 参数。这条线是我内存不足并进入看似无限循环的原因。
  • 另外,你的意思是&amp;&amp; $domain === 'woocommerce' 吗? is_wc_endpoint_ur() 是什么?
  • 要仅定位结帐页面(而不是使用自定义端点 order-received结帐的“收到订单”页面),您必须使用is_checkout() &amp;&amp; ! is_wc_endpoint_url()
  • 谢谢 - 所以如果我想定位“收到订单”页面,那么我将执行以下操作 if (is_checkout() &amp;&amp; is_wc_endpoint_url( 'order-received' )) - 这是正确的吗?
  • 谢谢。实际上,我仍然有一些小问题,您提供的代码不起作用 - 所以我试图弄清楚并且会回来,即使在我取出 get_my_custom_text() 之后仍然会看到一些无休止的循环。
【解决方案2】:

该方法很好,您可以将该函数添加到您的子主题中的functions.php

但是,下面的方法可能更好,因为您根本不需要修改 woocommerce!您仍然需要相同的功能,但现在一切都可以驻留在functions.php 中。这使用了 Wordpress 的 gettext filter

add_filter( 'gettext', 'my_text_strings', 20, 3 );
function my_text_strings( $translated_text, $text, $domain ) {

    switch ( $translated_text ) {
        case 'Total' :
            $translated_text = __( get_my_custom_text(), 'woocommerce' );
            break;
    }

    return $translated_text;
}

【讨论】:

  • 谢谢。我现在有一个新问题。在 get_my_custom_text() 中,我使用 global $woocommerce 确定购物车是否有杂货类别中的商品; $cart = $woocmmerce->cart;出于某种原因,它似乎不适用于这个钩子。我已经成功地使用相同的逻辑来确定是否有物品属于杂货类别。我错过了什么吗?
  • @Les,在确定 Woocommerce 购物车总数之前,可能会调用此过滤器。当您尝试上面发布的方法时,您是否遇到同样的问题?当您尝试$woocommerce-&gt;cart 时,什么不起作用?
  • 到处都有同样的问题。当我尝试$woocommerce-&gt;cart 时,我开始在 WC 日志CRITICAL Allowed memory size of 268435456 bytes exhausted (tried to allocate 20480 bytes) in /opt/wordpress/wp-includes/taxonomy.php on line 4157 上出现内存耗尽错误。网页变得无响应并变为空白。如何判断过滤器是否在 WC 购物车总计之前被调用?我还有其他选择来实现我想要的吗?
  • @Les 我不确定。你可以试试用这个吗? WC()-&gt;cart-&gt;get_cart_contents_count()
  • 我收到以下错误:未捕获的错误:在 null 上调用成员函数 get_cart_contents_count()。购物车有 1 件商品。
猜你喜欢
  • 2021-08-14
  • 2018-09-10
  • 2021-08-04
  • 2013-12-28
  • 2022-11-18
  • 2016-10-18
  • 1970-01-01
  • 2011-09-23
  • 2018-07-10
相关资源
最近更新 更多