Customize Cart Totals and Checkout Totals Text bas

2019-07-08 08:29发布

I'd like to customize the text in Cart and Checkout order summary tables based on the product category (or some other logic). For example, for the 'Total' text (see image) - if the cart contains products in a category called "Groceries", then I'd like for text in the order summary to be displayed as 'Totals Estimate' text (see image below). If the cart does not contain any grocery items, then I want the default text.

I found a solution that got me started, but need some more help.

Per this link, I copied over files from woocommerce/templates/ into my child theme and named it woocommerce/. From review_order.php file, I need to edit the section below for example.

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

However, I can't just replace that with a hard-coded string as my text depends on logic. So, I need to replace the string with a function.

I want to instead do something like this below:

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

, where get_my_custom_text() returns the appropriate text based on some logic e.g. categories of items in the cart.

  1. Where would I need to place the file containing function get_my_custom_text() so that the review_order.php can see the function?
  2. Is this the best way to achieve what I'm trying to do?

enter image description here

Update: Following discussions below, I'm adding my get_custom_text() code. I've attempted to solve this two ways: first is the woocommerce files way and second one is the suggestion below to use the add_filter( 'gettext', 'my_text_strings', 20, 3 ) hook. In both cases, get_my_custom_text() doesn't seem to work when inspecting the cart. See code below using the hook method. I've gotten an error on the get_cart_contents_count(), and also got the white screen of death

[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

Also got: [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;
        }

2条回答
一夜七次
2楼-- · 2019-07-08 09:01

That method is fine, and you would add the function to your functions.php in your child theme.

However, the method below is likely better, as you don't need to modify woocommerce at all! You'll still need your same function, but everything can reside in functions.php now. This uses Wordpress's 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;
}
查看更多
Juvenile、少年°
3楼-- · 2019-07-08 09:21

Why are you trying to get in the Log, the cart items count (in your function). This is not really useful.

I have simplified and revisited your code and I dont use get_my_custom_text() in the last function as using has_groceries() instead is simpler and effective:

// 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;
}

Code goes on function.php file of your active child theme (or active theme). Tested and works.

This way it will avoid an endless loop on "Total" text replacement.

查看更多
登录 后发表回答