Диагностика проблемы: зачем менять цену товара по языку
В WooCommerce на мультиязычных сайтах часто возникает задача отображать разные цены для одного и того же товара в зависимости от выбранного языка. Причины могут быть разные: локальные налоги, курсы валют, маркетинговые стратегии или особенности локального рынка. Стандартно WooCommerce с мультиязычными плагинами (WPML, Polylang) не меняет цену товара автоматически по языку, что приводит к необходимости ручного управления или кастомных решений.
Как определить, что требуется динамическое изменение цены
- Проверьте, одинаковы ли цены товара во всех языковых версиях.
- Убедитесь, что плагин мультиязычности не дублирует товар с разными ценами (что сложно поддерживать).
- Оцените, нужна ли автоматическая подстановка цены в зависимости от языка без создания дублей товара.
Пошаговое решение: динамическое изменение цены с помощью хука woocommerce_product_get_price
Для динамического изменения цены в зависимости от языка можно использовать фильтр WooCommerce woocommerce_product_get_price. Ниже пример кода, который изменяет цену товара в зависимости от текущего языка, определяемого через WPML:
add_filter('woocommerce_product_get_price', 'change_price_by_language', 10, 2);
add_filter('woocommerce_product_get_regular_price', 'change_price_by_language', 10, 2);
add_filter('woocommerce_product_get_sale_price', 'change_price_by_language', 10, 2);
function change_price_by_language($price, $product) {
if (function_exists('icl_object_id')) { // Проверка WPML
$current_lang = apply_filters('wpml_current_language', NULL);
switch ($current_lang) {
case 'ru':
// Цена для русского языка
$new_price = $price * 1; // без изменений
break;
case 'en':
// Цена для английского языка (например, +10%)
$new_price = $price * 1.1;
break;
case 'de':
// Цена для немецкого языка (скидка 5%)
$new_price = $price * 0.95;
break;
default:
$new_price = $price;
}
return $new_price;
}
return $price;
}Код обрабатывает три языка: русский, английский и немецкий, меняя цену товара динамически. Похожий подход применим и к другим плагинам мультиязычности, например, Polylang, с заменой определения текущего языка.
Особенности работы с вариативными товарами
Вариативные товары требуют дополнительно фильтровать цены вариаций:
add_filter('woocommerce_variation_prices_price', 'change_variation_price_by_language', 10, 3);
add_filter('woocommerce_variation_prices_regular_price', 'change_variation_price_by_language', 10, 3);
add_filter('woocommerce_variation_prices_sale_price', 'change_variation_price_by_language', 10, 3);
function change_variation_price_by_language($price, $variation, $product) {
// Аналогичная логика изменения цены
if (function_exists('icl_object_id')) {
$current_lang = apply_filters('wpml_current_language', NULL);
switch ($current_lang) {
case 'ru':
$new_price = $price;
break;
case 'en':
$new_price = $price * 1.1;
break;
case 'de':
$new_price = $price * 0.95;
break;
default:
$new_price = $price;
}
return $new_price;
}
return $price;
}Проверка результата после внедрения
- Переключитесь на разные языки сайта (через языковой переключатель).
- Откройте страницу товара и сравните отображаемую цену с ожидаемой.
- Проверьте корзину и оформление заказа, чтобы цена изменилась корректно.
- Для вариативных товаров проверьте цены каждой вариации.
Если цены меняются согласно выбранному языку, решение работает корректно.
Частые ошибки и как их исправить
- Цена не меняется: Проверьте, подключен ли фильтр и правильно ли определяется текущий язык. Для WPML используйте
apply_filters('wpml_current_language', NULL), для Polylang -pll_current_language(). - Кэширование мешает обновлению цен: Очистите кэш сайта и браузера, отключите кэширование на время тестирования.
- Цена меняется, но в заказе сохраняется старая цена: Добавьте фильтр
woocommerce_before_calculate_totalsдля принудительного обновления цен в корзине:
add_action('woocommerce_before_calculate_totals', 'update_cart_item_prices_by_language');
function update_cart_item_prices_by_language($cart) {
if (is_admin() && !defined('DOING_AJAX')) return;
foreach ($cart->get_cart() as $cart_item) {
$product = $cart_item['data'];
$price = change_price_by_language($product->get_regular_price(), $product);
$product->set_price($price);
}
}Практические советы по производительности и безопасности
- Не используйте сложные вычисления или внешние API в фильтре изменения цены — это может замедлить загрузку страниц.
- Кэшируйте результаты вычислений цен, если логика сложная.
- Проверяйте наличие плагина мультиязычности перед вызовом функций, чтобы избежать ошибок.
- Используйте дочернюю тему или плагин для внедрения кода, чтобы избежать потери изменений при обновлении.
Сравнение подходов изменения цены по языку
| Метод | Плюсы | Минусы |
|---|---|---|
| Создание дублирующих товаров с разными ценами | Простота управления через админку | Дублирование контента, сложность в учёте и отчётности |
| Использование кастомного фильтра цены (как в статье) | Единый товар, динамическое управление, меньше ошибок | Требует программирования, возможно конфликты с плагинами |
| Плагины для мультивалютности с редактором цен по языку | Удобный интерфейс, поддержка валют | Дополнительная нагрузка, стоимость лицензий |