wplang.ru wordpress WP Lang

WooCommerce: как динамически изменять стоимость товара в зависимости от выбранного языка

Проблема: разная стоимость товара для разных языков в WooCommerce

В мульти-язычных магазинах WooCommerce часто требуется показывать разную цену товара в зависимости от выбранного языка сайта. Например, цена в рублях для русского языка и в евро для английского. Стандартные решения плагинов мультиязычности не всегда поддерживают такую логику, или требуют покупки дополнительных расширений.

В этой статье разберём, как реализовать динамическое изменение цены товара на лету с помощью кода — без дополнительных плагинов для мультивалютности. Это подходит, если у вас фиксированные курсы и цены для каждого языка, а не сложные валютные конвертации.

Диагностика: почему стандартные методы не работают

Стандартный WooCommerce хранит цену товара в базе как одно значение. Плагины перевода, например WPML или Polylang, обычно не меняют цену, а переводят только текст. Отдельные плагины мультивалютности добавляют валюты и конвертации, но они часто тяжелые и сложные.

Если вы просто меняете язык сайта, но цена остаётся одинаковой, значит, нужно вмешаться программно и подменить цену при выводе.

Пошаговое решение: изменение цены товара по языку

1. Определяем язык сайта

Предположим, что у вас установлен плагин Polylang или WPML. Для WPML можно получить текущий язык так:

if (defined('ICL_LANGUAGE_CODE')) {
    $current_lang = ICL_LANGUAGE_CODE;
} else {
    $current_lang = 'ru';
}

Для Polylang:

$current_lang = function_exists('pll_current_language') ? pll_current_language() : 'ru';

2. Добавляем цены для языков в метаполя товара

Через админку добавьте произвольные поля для товаров, например price_ru и price_en с нужными значениями. Можно использовать ACF или стандартные метаполя.

3. Подменяем цену на фронтенде

Добавьте следующий код в functions.php вашей темы или в кастомный плагин:

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 (defined('ICL_LANGUAGE_CODE')) {
        $current_lang = ICL_LANGUAGE_CODE;
    } elseif (function_exists('pll_current_language')) {
        $current_lang = pll_current_language();
    } else {
        $current_lang = 'ru';
    }

    // Получаем ID товара
    $product_id = $product->get_id();

    // Названия метаполей с ценами для языков
    $price_meta_key = 'price_' . $current_lang;

    // Получаем цену из метаполя
    $custom_price = get_post_meta($product_id, $price_meta_key, true);

    // Если цена задана и больше 0, возвращаем её
    if ($custom_price !== '' && floatval($custom_price) > 0) {
        return $custom_price;
    }

    // Иначе возвращаем оригинальную цену
    return $price;
}

4. Обновляем кэш и проверяем

Очистите кэш сайта и браузера. Зайдите на страницу товара, переключайте язык и проверьте, что цена меняется в соответствии с указанными метаполями.

Проверка результата после внедрения

  • Откройте страницу товара на основном языке (например, ru) — должна отображаться цена из price_ru.
  • Переключитесь на другой язык (en) — цена должна обновиться на значение из price_en.
  • Проверьте и корзину — цены должны соответствовать выбранному языку.
  • Если есть скидки, они применяются к подставленной цене.

Частые ошибки и как исправить

  • Цена не меняется при смене языка: проверьте, правильно ли определён язык, и действительно ли заполнены метаполя price_xx.
  • Цена выводится некорректно (например, пустая или 0): убедитесь, что метаполя содержат числовые значения без лишних символов.
  • Кэш мешает обновлению цены: очистите кэш плагинов (например, WP Rocket, LiteSpeed) и браузера.
  • В корзине или на странице оформления заказа цена не обновляется: для корректного изменения цены в корзине нужно добавить следующий фильтр:
add_action('woocommerce_before_calculate_totals', 'change_cart_item_price_by_language', 20, 1);
function change_cart_item_price_by_language($cart) {
    if (is_admin() && !defined('DOING_AJAX')) {
        return;
    }
    
    if (defined('ICL_LANGUAGE_CODE')) {
        $current_lang = ICL_LANGUAGE_CODE;
    } elseif (function_exists('pll_current_language')) {
        $current_lang = pll_current_language();
    } else {
        $current_lang = 'ru';
    }

    foreach ($cart->get_cart() as $cart_item) {
        $product = $cart_item['data'];
        $product_id = $product->get_id();
        $price_meta_key = 'price_' . $current_lang;
        $custom_price = get_post_meta($product_id, $price_meta_key, true);
        if ($custom_price !== '' && floatval($custom_price) > 0) {
            $product->set_price($custom_price);
        }
    }
}

Практические советы по безопасности и производительности

  • Используйте префиксы для метаполей, чтобы избежать конфликтов.
  • Не храните цены в нечисловом формате — это может привести к ошибкам при подсчётах.
  • Кэшируйте результаты, если у вас большой каталог и сложная логика.
  • Для поддержки нескольких валют лучше использовать специализированные плагины, если требуется автоматическое обновление курса.

Сравнение подходов изменения цены по языку

МетодПлюсыМинусыРекомендации
Использование метаполей и фильтров (код)Легко настроить, нет лишних плагинов, полный контрольТребует ручного заполнения цен, не подходит для динамических курсовДля небольших магазинов с фиксированными ценами под каждый язык
Плагины мультивалютностиАвтоматическое обновление курсов, поддержка нескольких валютСложность настройки, нагрузка на сайт, возможные конфликты с плагинами переводаДля магазинов с динамическим ценообразованием и большим ассортиментом
Отдельные сайты под каждый языкМаксимальный контроль и гибкостьДорого и неудобно для поддержкиДля очень крупных проектов или когда требуется очень разная ценовая политика
×
Сделай свой сайт крутым!

Скидка -20% на премиум плагины WordPress

Выбрать плагин сейчас ⋙