qtranslate / qtranslate-xt

qTranslate-XT (eXTended) - reviving qTranslate-X multilingual plugin for WordPress. A new community-driven plugin soon. Built-in modules for WooCommerce, ACF, slugs and others.
GNU General Public License v2.0
557 stars 107 forks source link

WooCommerce translation issues #949

Open BenceSzalai opened 3 years ago

BenceSzalai commented 3 years ago

I'm wondering if anyone is facing similar. I have the latest qTranslate-XT (v3.9.2) and WooCommerce (v4.9.2) and the latest WP (v5.6), but some parts are not properly translated or translatable.

One thing to note that I've turned off the Filter all WordPress options for translation at front-end option under Advanced in the hope to improve site performance. I guess with that option turned on, many of my issues would be solved, as many of the configuration for WooCommerce are indeed stored as options, including the text fields.

So one of my questions is that how heavily you reckon WooCommerce integration module relies on the Filter all WordPress options for translation at front-end setting? I assume the best config is if only specific options are translated, maybe together with some filters instead of translating all options, which may impact site performance.

To fix these translations I've started to look for filters I can hook into translation. I could fix the translations in the email templates by adding these to my custom i18n-config.json:

{
  ...
  "front-config": {
    "all-pages": {
      "filters": {
        "text": {
          "woocommerce_email_heading_cancelled_order": "20",
          "woocommerce_email_heading_customer_completed_order": "20",
          "woocommerce_email_heading_customer_invoice": "20",
          "woocommerce_email_heading_customer_note": "20",
          "woocommerce_email_heading_customer_on_hold_order": "20",
          "woocommerce_email_heading_customer_processing_order": "20",
          "woocommerce_email_heading_customer_refunded_order": "20",
          "woocommerce_email_heading_customer_reset_password": "20",
          "woocommerce_email_heading_failed_order": "20",
          "woocommerce_email_heading_new_order": "20",

          "woocommerce_email_subject_cancelled_order": "20",
          "woocommerce_email_subject_customer_completed_order": "20",
          "woocommerce_email_subject_customer_invoice": "20",
          "woocommerce_email_subject_customer_note": "20",
          "woocommerce_email_subject_customer_on_hold_order": "20",
          "woocommerce_email_subject_customer_processing_order": "20",
          "woocommerce_email_subject_customer_refunded_order": "20",
          "woocommerce_email_subject_customer_reset_password": "20",
          "woocommerce_email_subject_failed_order": "20",
          "woocommerce_email_subject_new_order": "20",

          "woocommerce_email_additional_content_cancelled_order": "20",
          "woocommerce_email_additional_content_customer_completed_order": "20",
          "woocommerce_email_additional_content_customer_invoice": "20",
          "woocommerce_email_additional_content_customer_note": "20",
          "woocommerce_email_additional_content_customer_on_hold_order": "20",
          "woocommerce_email_additional_content_customer_processing_order": "20",
          "woocommerce_email_additional_content_customer_refunded_order": "20",
          "woocommerce_email_additional_content_customer_reset_password": "20",
          "woocommerce_email_additional_content_failed_order": "20",
          "woocommerce_email_additional_content_new_order": "20",

          "woocommerce_gateway_title": "20"
        }
      }
    }
  }
}

However I couldn't find a suitable filter for example for the shipping methods title and descriptions, so after all I've just added woocommerce_%_settings under Translation of options. That fixed my issues on the frontend.

Note this may not be an issue for most, as some of those fields are not configured as translatable in the admin by default, but they really should be. As the payment and shipping methods title and description appears on the frontend also in the emails it is mandatory for a multilingual site to be able to translate those. For that reason I've added these to my i18n-config.json too:

{
  ...
  "admin-config": {
    "woocommerce_config": {
      "pages": {"edit.php":"post_type=product&page=product_attributes"},
      "forms":{
        "wpbody":{
          "fields":{
            "attribute_label":{"encode":"["},
            "attribute_name":{"encode":"["}
          }
        }
      }
    },
    "woocommerce-gateway-paypal-express-checkout": {
      "pages": {"admin.php":"page=wc-settings&tab=checkout&section=ppec_paypal"},
      "forms":{
        "mainform":{
          "fields":{
            "woocommerce_ppec_paypal_title":{"encode":"["},
            "woocommerce_ppec_paypal_description":{"encode":"["}
          }
        }
      }
    },
    "all-pages": {
      "filters": {
        "text": {
          "woocommerce_gateway_title": "20"
        }
      }
    }
  },
  ...
}

(Side note, I couldn't enable the translation on the Admin UI for the shipping method fields, as those are loaded using JS dynamically into the page, but that's not a big issue as I can just type manually the [:...] codes into the fields.)

So my second question is do you think it is okay, what I've done, or I am having an issue with the WooCommerce integration module and these things should work out of the box? And if not so, could we / shouldn't we extend/fix the WooCommerce integration module somehow to support these use cases too?

herrvigg commented 3 years ago

Thank you for looking at this. I must admit i never cared about that filter option mode, i've always used the default. The related code comes from the qtranxf_filter_options function:

https://github.com/qtranslate/qtranslate-xt/blob/e9d0748170acef17448238afaf7ebf0185e839a0/qtranslate_frontend.php#L412-L440

I have never looked at the performance of this. Perhaps it could be improved by refining a bit the WHERE query, or maybe building some index. I performance were really an issue it would be nice to find a solution that is maybe more generic.

I haven't look at the impact of your changes in detail yet, but spontaneously i have these remarks:

[Update: the topic about the filter is moved to #961]

herrvigg commented 3 years ago

qtranxf_filter_options should only apply to the front config, but the relation is not very clear to me yet.

Oh now it's obvious, the function is loaded in qtranslate_frontend.php so this should not apply to any option on the admin side.

BenceSzalai commented 3 years ago

Well, I didn't meant it all relate to WC options. I just wanted to get WC working fine in a bilingual site, and those i18n-config.json settings are what it took me. If we go part-by-part:

In fact anyone can customise their email templates, in which case they may need other filters or they may pass some of these raw text through __() to ensure they are translated, but the default emails are fine for many cases, and they should work I think out of the box.

As I said the shipping methods are also included in the emails, but I couldn't identify a suitable filter for those, however each shipping method is stored in the options table as woocommerce_{shipping_class_slug}_{shipping_method_id}_settings, e.g.: woocommerce_flat_rate_1_settings or woocommerce_free_shipping_3_settings etc.

As for the admin side of the things:

And the part I couldn't fix using the i18n-config.json is this: Shipping method title 1 Shipping method title 2 But these are fine on the FE once woocommerce_%_settings options are included in translation, however on the admin I cannot really configure them as they are loaded using JS, not part of the normal HTML forms.

BenceSzalai commented 3 years ago

In fact the slug should not be translatable for Attributes, so the correct config for that is this:

i18n-config.json too:

{
  ...
  "admin-config": {
    "woocommerce_config": {
      "pages": {"edit.php":"post_type=product&page=product_attributes"},
      "forms":{
        "wpbody":{
          "fields":{
            "attribute_label":{"encode":"["}
          }
        }
      }
    }
  ...
}

So only the labels (called "Name" on the UI) are translatable: product attributes' config

herrvigg commented 3 years ago

@BenceSzalai First, thank you for all the details! It's well documented and you provide a very good level of information, much appreciated.

But i see at least two different topics and it's becoming difficult to follow everything. The initial topic was about disabling "Filter all WordPress options" and a question of performance to get the correct behavior. But after that most of the discussion changed to missing translations, mostly in the admin side and a few for the front side. Since you provided many screenshots here, i suggest we move the discussion about the "Filter all WordPress options" to a different ticket.

I was starting to wonder how to add your changes in the modules and i realized the i18n-config.json is not supported natively in the modules. See #958. So i will rather convert this to PHP code in the modules for now.

Now let's take every point one by one:

Please check these points and let's see what we can do here. I hope i didn't forget anything.

BenceSzalai commented 3 years ago

Sorry for mixing those topics.

herrvigg commented 3 years ago

Thanks for breaking the filter part, it will be easier to track. So here we just have woocommerce_gateway_title left.

BenceSzalai commented 3 years ago

I suggest we refine it instead with a query for a regular page entry, for display only. It's better to make it more specific to avoid any side effect.

Sorry, I cannot really get this. De you mean to use more specific page instead of "all-pages" or do you mean to implement this in PHP instead of i18n-config.json.

herrvigg commented 3 years ago

Admin / woocommerce_gateway_title I meant to add an entry in qtranxf_wc_add_admin_page_config with a specific pages regex query. But i've tested this and the translation works for me without adding woocommerce_gateway_title. The whole payment block is contained in a <p class="woocommerce-order-data__meta order_number">. So that's captured by $fields['order_number'] = array( 'jquery' => '.order_number', 'encode' => 'display' );. I can't see any woocommerce_gateway_title in my case. Can you check again? Why would it be different?

Front / woocommerce_gateway_title

My guess is that when WooCommerce sends the emails it is really a backend process and probably $url_info['doing_front_end'] is false in qwc_init_language(), so the whole qwc-front.php may not be loaded.

There is a check on wp_doing_cron(). In that case, the front filters are not added. The reason is explained in the legacy plugin in version 1.4 :

  • Improvement: Filters are disabled if DOING_CRON is defined. This enables Woocommerce API to send information in raw ML format.

So I don't really know what to do here. If doing_front_end is false, it should run the admin part. Maybe the email is triggered from the admin side, and you had actually another hook doing the job?

herrvigg commented 3 years ago

@BenceSzalai any update about these two points for woocommerce_gateway_title ? I plan to release a new patch soon, would be good if we can close this point with next release.

BenceSzalai commented 3 years ago

Admin / woocommerce_gateway_title

I see what you mean, but for some reason the .order_number jquery filter seems to not work for me. If I remove the woocommerce_gateway_title filter, this is what appears on my order admin page:

<p class="woocommerce-order-data__meta order_number">
Payment via [:hu]Utánvétes fizetés[:en]Payment on Delivery[:]. Customer IP: <span class="woocommerce-Order-customerIP">xx.xx.xx.xx</span>
</p>

I've tested the selector, and it seems to be fine, but the text is not translated anyway:

14:22:55.667 jQuery('.order_number')
14:22:55.701
Object { 0: p.woocommerce-order-data__meta.order_number, length: 1, prevObject: {…} }

The $fields['order_number'] = array( 'jquery' => '.order_number', 'encode' => 'display' ); here does not seem to do anything. I don\t know how it is really supposed to load the related config on the admin. I've checked but seen no scripts loaded from wp-content/plugins/qtranslate-xt-3.9.2, also searched in the dom inspector, but get no hits for order_number, so I couldn't verify if the config is loaded properly on my order edit page...

I can't see any woocommerce_gateway_title in my case. It is a filter I've found in wp-content/plugins/woocommerce/includes/abstracts/abstract-wc-payment-gateway.php:

//...
abstract class WC_Payment_Gateway extends WC_Settings_API {
//...
public function get_title() {
return apply_filters( 'woocommerce_gateway_title', $this->title, $this->id );
}
//...
}

I've set it up as the solution for the issue I've highlighted here.

Front / woocommerce_gateway_title

So I don't really know what to do here. If doing_front_end is false, it should run the admin part.

Right, since the woocommerce_gateway_title filter is always applied to the gateway title, because it is part of the WC_Payment_Gateway::get_title() method, I've configured this filter for all admin pages, i.e. without a page filter, so it runs when the emails are being sent. I don't think wp-cron is involved with sending the emails, but it is a guess only.

If you have any specific questions about my setup, let me know!

herrvigg commented 3 years ago
BenceSzalai commented 3 years ago