BEAR - WooCommerce Bulk Editor and Products Manager Professional

Bulk edit WooCommerce prices in all WPML languages (and Polylang)

You lower a hundred prices in the bulk editor, check the shop in English and see the new prices, then switch to German and see the old ones. With WPML, a WooCommerce bulk edit of prices in all languages needs one more step than in a single-language shop, because every translation of a product is a product of its own. This page explains which language BEAR edits, how to make prices follow to every translation with one filter, how to do the same for stock, weight and other fields, and what to edit per language on purpose.

How BEAR works with WPML: one language at a time

WPML does not store a translated product inside the original. It creates a second WooCommerce product with its own ID, its own prices, stock and meta data, and links the two in a translation group. BEAR sees those products as WooCommerce does, so:

  • The Products Editor lists the products of the language selected in WPML's language switcher at the top of the admin screen. Switch the language there and the editor shows that language's products.
  • Filters, the Bulk Edit tab and the export work on the listed products, that is on one language. A bulk run in English changes the English products only.
  • BEAR writes to the product you edit and to nothing else. WPML's own copying of fields to translations is built around saving the original on the product edit screen, and a write from the bulk editor does not reliably trigger it. Do not count on it for a catalogue-wide change.

Pick one specific language in the switcher before you start, and check which language you are in before every bulk run. The WPML compatibility note states the same rule: the products of each language are bulk edited separately. The two sections below are the ways to make a change reach the other languages anyway.

Sync prices to all WPML languages with woobe_wpml_sync_prices

For prices, BEAR has a built-in switch. Add this filter:

/*
 * BEAR + WPML: write regular and sale prices to all translations.
 * Child theme functions.php or a code snippets plugin.
 */
add_filter( 'woobe_wpml_sync_prices', '__return_true' );

From then on, every time BEAR writes a regular price above zero or a sale price to a product, it writes the same value to that product's translations in every WPML language. It does not matter how the price was written: typed into a cell, set with the price calculator, changed by value or percentage in the Bulk Edit tab, or put back by a revert in History. Variations are covered too: the price of a variation goes to the translated variations. Removing a sale price with -1, as described in how to bulk remove sale prices, also clears it in the translations.

Three things to know before you rely on it:

  • The same number is written to every language. That is right when all languages sell in the same currency. If a language should have its own price, leave the filter off and edit that language separately.
  • Sale dates are not part of it. A sale price copied to the translations without its Sale time from and Sale time to is active in those languages at once. Either set the dates in every language or copy them with the snippet in the next section.
  • Only edits made after the filter was added are copied. Prices that already differ stay as they are until the next write.

The filter is listed with the other code-level switches in More settings (implicit).

Copy stock, weight, dimensions and other fields to translations

Every field BEAR writes ends with the action woobe_after_update_page_field, which receives the product ID, the product object, the field key, the value and the field type. A small function hooked to it can repeat the change on every translation. This one copies stock, shipping data, tax class and sale dates:

/*
 * BEAR + WPML: copy chosen product fields from the edited product
 * to its translations in all languages.
 * Child theme functions.php or a code snippets plugin.
 */
add_action( 'woobe_after_update_page_field', function ( $product_id, $product, $field_key, $value, $field_type ) {

	// BEAR field keys to copy; each one is a WooCommerce product property
	$copy = array(
		'stock_quantity', 'stock_status', 'manage_stock', 'backorders',
		'weight', 'length', 'width', 'height', 'tax_class',
		'date_on_sale_from', 'date_on_sale_to',
	);

	if ( ! in_array( $field_key, $copy, true ) || ! defined( 'ICL_SITEPRESS_VERSION' ) ) {
		return;
	}

	$source = wc_get_product( $product_id );
	if ( ! $source ) {
		return;
	}

	$getter = 'get_' . $field_key;
	$setter = 'set_' . $field_key;
	$new    = $source->$getter( 'edit' );
	$type   = get_post_type( $product_id ); // product or product_variation

	foreach ( (array) apply_filters( 'wpml_active_languages', null ) as $code => $language ) {
		$translation_id = (int) apply_filters( 'wpml_object_id', $product_id, $type, false, $code );

		if ( ! $translation_id || $translation_id === (int) $product_id ) {
			continue;
		}

		$translation = wc_get_product( $translation_id );
		if ( $translation ) {
			$translation->$setter( $new );
			$translation->save();
		}
	}
}, 10, 5 );

How to use it well:

  • Edit one product in the editor first and look at its translation. When the value has arrived, run the bulk edit.
  • The function copies from whichever language you edit to all the others. Do these edits in your main language and treat it as the source.
  • It runs on every write that goes through BEAR, History reverts included, so a revert of the original also puts the translations back.
  • Add or remove keys in the $copy list as you need. Keep text fields out of it (title, descriptions, slug): those are what translations exist for.
  • SKU is left out on purpose. WooCommerce refuses a SKU that another product already uses, so copying it can fail depending on how your WPML setup treats _sku. Set SKUs per language, or check that setup first.

If WooCommerce Multilingual already keeps stock in step between translations on your shop, copying the stock fields is harmless: the same number is written twice. Bulk stock work itself is covered in BEAR as a WooCommerce stock manager.

What to edit in each language

Titles, descriptions, short descriptions, slugs, purchase notes and anything else that is written in words belong to one language. Edit them per language: switch the language in the admin bar, filter, and run the bulk edit. Repeat for the next language.

Filters work on the values stored in the products of the current language. Categories, tags and attribute terms are translated too, so a filter built in English points to English terms; build it again after switching. A filter by a meta field finds only translations that hold that value themselves, so a field that WPML does not copy can be empty in a translation and the filter finds nothing there. Fields that WPML is set to copy are best changed in the original language, so that the next save on WPML's side does not bring the old value back.

If only a few products missed a change, opening the original in the WooCommerce product editor and pressing Update lets WPML run its own copying for that product. For a catalogue, use the filter or the snippet above.

New and duplicated products

The New Product button of the editor creates drafts named New Product through WooCommerce's own product API, in the background. WPML gives them a language as it does for any post created that way, normally the language selected in the admin bar. Switch to the language you want before creating, and check the language of the new drafts afterwards; fix any stray one in WPML.

Duplicating products in the editor uses WooCommerce's duplicate function and fires the same woocommerce_product_duplicate action as the Duplicate link on the Products screen. Translation plugins that also copy the translations of a duplicated product do it on that action, so a duplicate may arrive together with copies in the other languages. Reload the editor to see the final state, and check the categories of every language's copy.

Polylang

BEAR has no Polylang-specific code. It edits the product you see; whether a change reaches the translations depends on the synchronisation of Polylang for WooCommerce, which may or may not react to a bulk write the way it reacts to the product edit screen. Test it on one product before a bulk run, and if the translations do not follow, edit each language separately. The same applies to duplicates: BEAR copies a duplicate's custom taxonomies but leaves Polylang's language and translation links alone, so the language of the copies and their categories come from Polylang. Check both after duplicating.

Checklist for a multilingual bulk edit

  • The language switcher shows the language you mean to edit, not the one you used last.
  • Prices: woobe_wpml_sync_prices is on if every language should get the same price, off if they differ.
  • Sale dates, stock, weight and dimensions: copied by the snippet, or edited in every language.
  • Text fields: edited per language, never copied.
  • One product tested and its translation checked before the bulk run; History open to revert if the result is wrong.

If translations still do not follow a change, open a topic on the BEAR support forum with your WPML and WooCommerce Multilingual versions, the field you edited and what the translated product shows afterwards.