Polylang wc compatibility
Skill Lonsdale201/wp-agent-skills/polylang/polylang-wc-compatibility
A community-maintained collection of agent skills for WordPress plugin and theme development.
npx -y skills add Lonsdale201/wp-agent-skills --skill polylang-wc-compatibilityAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 21 stars21 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Build WooCommerce plugins and themes that are compatible with Polylang for WooCommerce 2.2.2. Covers product and variation language data stores, product/order translation groups, cart and Store API language behavior, HPOS order filtering, lang query behavior, SKU/global unique ID per-language checks, product property and attribute translation, stock/reserved stock sync, Woo REST lang/translations fields, batch create language queues, translated Woo strings/options, and hooks such as pllwc_copy_post_metas, pllwc_translate_product_meta, pllwc_translate_product_prop, pllwc_enable_cart_translation, pllwc_language_for_unique_sku, pllwc_get_order_types, and pllwc_copy_product. Use when extending Woo products, variations, orders, Store/REST integrations, stock, attributes, gateways, shipping, or emails on a Polylang multilingual shop.
SKILL.md
11.4 KB, as published. Nobody here has run it
Polylang for WooCommerce Compatibility
Use this skill when WooCommerce code must work correctly on a shop using Polylang for WooCommerce.
Polylang WC is not just "Polylang applied to products". It adds Woo-specific data stores, variation sync, stock sync, SKU checks, order language behavior, HPOS handling, Woo REST integration, and Woo settings string translation.
Detect and guard
if ( ! class_exists( 'PLLWC_Data_Store' ) || ! function_exists( 'pll_current_language' ) ) {
return;
}
Local source checked: Polylang for WooCommerce 2.2.2, minimum Polylang 3.7, WooCommerce required, Woo REST module requires Polylang Pro 3.8+.
Product language store
Use the Woo-aware language store for products and variations:
$store = PLLWC_Data_Store::load( 'product_language' );
$lang = $store->get_language( $product_id );
$fr_id = $store->get( $product_id, 'fr' );
$translations = $store->get_translations( $product_id );
The product store wraps Polylang's post model, but centralizes Woo-specific behavior. Prefer it in Woo integration code.
When creating products programmatically:
$product = new WC_Product_Simple();
$product->set_name( 'Coffee' );
$product->set_regular_price( '12.00' );
$product_id = $product->save();
$store = PLLWC_Data_Store::load( 'product_language' );
$store->set_language( $product_id, 'en' );
After creating a translation, save the group:
$store->set_language( $fr_product_id, 'fr' );
$store->save_translations( array(
'en' => $product_id,
'fr' => $fr_product_id,
) );
product and product_variation are added to translated post types but hidden from Polylang settings. Do not let users toggle these manually from your plugin.
Product queries and lang
Polylang filters Woo product queries by current language unless lang is explicitly set.
Use:
$products = wc_get_products( array(
'status' => 'publish',
'lang' => 'fr',
) );
For all languages, pass an explicit empty string:
$products = wc_get_products( array(
'limit' => -1,
'lang' => '',
) );
Polylang WC restores lang => '' after WooCommerce removes empty values in WC_Data_Store_WP::get_wp_query_args(). Missing lang means current language; explicit empty lang means all languages.
Variations and attributes
Polylang WC synchronizes variation language from the parent product and copies/synchronizes variations across translated variable products.
Important behavior:
woocommerce_variable_children_argsis forced tolang => ''so a variable product can see all child variations.- Variation data store is decorated to read attribute terms in the variation's language.
- Attribute slugs are translated when copied between languages.
- Product attributes lookup queries are temporarily filtered to the product language.
Do not manually clone variation posts without setting language and linking translations. Use Woo product objects and let Polylang WC hooks run, or call the product language store explicitly.
For custom product properties that store translated post/term IDs, use pllwc_translate_product_prop. Translate only your property, map product IDs through PLLWC_Data_Store::load( 'product_language' )->get( $id, $lang ), and return the original value for unknown properties.
Product meta copy/sync
Polylang WC maps legacy product meta keys to Woo product properties and decides which fields to copy or synchronize.
Customize with pllwc_copy_post_metas( array $keys, bool $sync, int $from, int $to, string $lang ): remove runtime/cache keys, add shared keys that must travel to translations, and guard by product type.
Translate copied product meta values with pllwc_translate_product_meta( $value, string $key, string $lang, int $from, int $to ). Use it for attachment, product, term, or page IDs stored in custom meta.
Avoid raw update_post_meta() loops that bypass Woo product setters. Woo lookup tables and cache invalidation matter.
Stock and reserved stock
Polylang WC synchronizes stock across product translations by filtering Woo's stock update SQL:
woocommerce_update_product_stock_querywoocommerce_updated_product_stockwoocommerce_query_for_reserved_stock
Do not update _stock, _stock_status, or reserved stock SQL manually for one translation. Use Woo stock APIs:
$product = wc_get_product( $product_id );
if ( $product ) {
wc_update_product_stock( $product, 5, 'set' );
}
The plugin updates lookup tables and clears caches for translated products after stock changes.
Cart, checkout, and Store API
Polylang WC translates cart contents by product language when cart translation is enabled. Relevant hooks:
pllwc_enable_cart_translationcan disable cart translation for incompatible third-party cart data.pllwc_translated_cart_itemfires after a cart item key/product has been translated.pllwc_translate_cart_contentsfilters the translated cart contents.
Do not store untranslatable product IDs in opaque cart item data. If custom cart data contains product, variation, term, or attachment IDs, translate those IDs when Polylang WC translates the cart.
PLLWC_Store_Blocks adds lang to /wc/store/v1 cart and checkout requests, prehydrates /wc/store/v1/cart?lang={current} and checkout data, translates product IDs in reviews-by-product blocks, and ensures the order language on woocommerce_store_api_checkout_order_processed.
For custom Store API calls, preserve the lang parameter or add it from pll_current_language() when calling /wc/store/v1/*. Do not assume Store API checkout orders will inherit the right language if your code bypasses Woo's Store API processing hooks.
SKU and global unique ID
Polylang WC makes SKU/global unique ID uniqueness language-aware:
wc_product_has_unique_skuwc_product_pre_lock_on_skuwc_product_has_global_unique_id
Dynamic language filters include:
pllwc_language_for_unique_skupllwc_language_for_lock_on_skupllwc_language_for_global_unique_id
Do not run your own global SKU uniqueness query without considering language. You may block valid translated products that intentionally share SKU.
Orders and HPOS
Order language uses the order language data store:
$orders = wc_get_orders( array(
'type' => 'shop_order',
'lang' => 'fr',
) );
Polylang WC translates shop_order and, internally, shop_order_placehold. It removes order post types from bulk translate actions.
Custom order types can opt in:
add_filter( 'pllwc_get_order_types', static function ( array $types, string $context ): array {
$types[] = 'shop_order_mytype';
return $types;
}, 10, 2 );
For HPOS, PLLWC_HPOS_Orders_Query filters woocommerce_orders_table_query_clauses by joining term relationships on the orders table alias. If your code builds custom HPOS SQL, you must add equivalent language filtering or use Woo order query APIs with lang.
Woo REST
With Polylang Pro 3.8+, Polylang WC owns Woo REST handling for products, variations, orders, product categories/tags/brands, and product attribute terms.
Product REST supports lang and translations; batch create routes read each create item's lang into a FIFO queue because a new product or term has no language yet. Order REST filtering accepts URLs such as /wp-json/wc/v3/orders?lang=fr.
Do not rely on generic Polylang Pro REST post handling for Woo products/orders. Polylang WC removes those types from generic Pro handlers and registers Woo-aware handlers.
Woo strings and options
Polylang WC registers and translates Woo email copy, store notices, checkout privacy/terms text, gateway/shipping titles, pickup location text, and checkout block payment method option strings.
If your Woo extension stores customer-facing settings in a WC_Settings_API object, expose stable option keys and sanitize text. Polylang WC can translate known shipping/gateway settings through PLL_Translate_Option and string registration.
Common mistakes
- Treating products as ordinary posts in import/sync code.
- Querying all products without
lang => ''and then missing translations. - Cloning variations without language and translation groups.
- Blocking shared SKUs globally instead of per language.
- Updating stock meta directly on one translation.
- Writing custom HPOS SQL without language joins.
- Assuming Polylang core REST fields apply to Woo REST without Polylang Pro and Polylang WC.
Cross-references
- Use
polylang-object-translationsfor generic post/term linking. - Use
polylang-rest-headlessfor RESTlangandtranslationssemantics. - Use
wc-hpos-compatibilityfor general Woo HPOS plugin rules. - Use
wc-store-apifor shopper-facing Store API rules.
Verification
Local source checked against src/data-store.php, src/product-language-cpt.php, src/order-language-cpt.php, src/products.php, src/frontend/frontend-cart.php, src/store-blocks.php, src/variation-data-store-cpt.php, src/stock.php, src/hpos-orders-query.php, and src/modules/REST/*.
References
- Official documentation: https://polylang.pro/doc/polylang-for-woocommerce/
- Official documentation: https://polylang.pro/doc/function-reference/
- Verified source paths:
wp-content/plugins/polylang-wc/polylang-wc.phpwp-content/plugins/polylang-wc/src/data-store.phpwp-content/plugins/polylang-wc/src/object-language.phpwp-content/plugins/polylang-wc/src/translated-object-language.phpwp-content/plugins/polylang-wc/src/product-language-cpt.phpwp-content/plugins/polylang-wc/src/order-language-cpt.phpwp-content/plugins/polylang-wc/src/products.phpwp-content/plugins/polylang-wc/src/frontend/frontend-cart.phpwp-content/plugins/polylang-wc/src/store-blocks.phpwp-content/plugins/polylang-wc/src/stock.phpwp-content/plugins/polylang-wc/src/variation-data-store-cpt.phpwp-content/plugins/polylang-wc/src/hpos-orders-query.phpwp-content/plugins/polylang-wc/src/strings.phpwp-content/plugins/polylang-wc/src/modules/REST/Module.phpwp-content/plugins/polylang-wc/src/modules/REST/Translated/Product.phpwp-content/plugins/polylang-wc/src/modules/REST/Translated/Batch.phpwp-content/plugins/polylang-wc/src/modules/REST/Filtered/Order.php