Налаштування мультимовності та мультивалютності OpenCart

Наша компанія займається розробкою, підтримкою та обслуговуванням сайтів будь-якої складності. Від простих односторінкових сайтів до масштабних кластерних систем, побудованих на мікро сервісах. Досвід розробників підтверджено сертифікатами від вендорів.

Розробка та обслуговування будь-яких видів сайтів:

Інформаційні сайти або веб-програми
Сайти візитки, landing page, корпоративні сайти, онлайн каталоги, квіз, промо-сайти, блоги, ресурси новин, інформаційні портали, форуми, агрегатори
Сайти або веб-програми електронної комерції
Інтернет-магазини, B2B-портали, маркетплейси, онлайн-обмінники, кешбек-сайти, біржі, дропшиппінг-платформи, парсери товарів
Веб-програми для управління бізнес-процесами
CRM-системи, ERP-системи, корпоративні портали, системи управління виробництвом, парсери інформації
Сайти або веб-програми електронних послуг
Дошки оголошень, онлайн-школи, онлайн-кінотеатри, конструктори сайтів, портали надання електронних послуг, відеохостинги, тематичні портали

Це лише деякі з технічних типів сайтів, з якими ми працюємо, і кожен із них може мати свої специфічні особливості та функціональність, а також бути адаптованим під конкретні потреби та цілі клієнта.

Пропоновані послуги
Показано 1 з 1 послугУсі 2065 послуг
Налаштування мультимовності та мультивалютності OpenCart
Середня
~2-3 робочих дні
Часті питання

Наші компетенції:

Етапи розробки

Останні роботи

  • image_website-b2b-advance_0.png
    Розробка сайту компанії B2B ADVANCE
    1262
  • image_web-applications_feedme_466_0.webp
    Розробка веб-додатків для компанії FEEDME
    1171
  • image_websites_belfingroup_462_0.webp
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    874
  • image_ecommerce_furnoro_435_0.webp
    Розробка інтернет магазину для компанії FURNORO
    1094
  • image_crm_enviok_479_0.webp
    Розробка веб-додатків для компанії Enviok
    831
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Розробка веб-сайту для компанії ФІКСПЕР
    851

Налаштування мультиязичності та мультивалютності OpenCart

OpenCart спочатку спроектована з підтримкою кількох мов та валют — це не додаток, а частина ядра. Але «працює з коробки» і «налаштовано правильно» — різні речі. Тут розглянемо повний цикл налаштування, включаючи SEO-URL для кожної мови, автооновлення курсів та коректне відображення цін для різних ринків.

Установка мов

OpenCart постачається з англійською мовою (en-gb). Для додавання російської, білоруської та інших мов потрібно:

1. Завантажити мовний пакет.

Офіційні мови доступні на opencart.com або github.com/opencart/opencart. OpenCart 4.x структура мовного пакета:

ru-ru.zip
├── admin/language/ru-ru/
│   ├── common/
│   ├── catalog/
│   ├── customer/
│   └── ...
└── catalog/language/ru-ru/
    ├── common/
    ├── product/
    ├── checkout/
    └── ...

2. Встановити через Extension Installer:

Extensions → Extension Installer → Upload → ru-ru.zip

3. Активувати мову:

System → Localization → Languages → Add Language
→ Language Name: Українська
→ Code: uk-ua
→ Locale: uk_UA.UTF-8
→ Image: flag/ua.png
→ Directory: uk-ua
→ Sort Order: 1
→ Status: Enabled

Прапори країн для перемикача — PNG-файли в catalog/view/image/flags/. Розмір: 16×11 px або 24×16 px.

4. Встановити за замовчуванням:

System → Settings → Local
→ Language: Українська
→ Administration Language: Українська (для панелі управління)

Мовні файли та переводи

Кастомні рядки в модулях або темах додаються через мовні файли:

// catalog/language/uk-ua/module/mymodule.php
$_['heading_title']   = 'Мое расширение';
$_['text_add_cart']   = 'У кошик';
$_['text_in_stock']   = 'В наявності';
$_['text_out_stock']  = 'Нема в наявності';
$_['text_preorder']   = 'Передзамовлення';
$_['error_required']  = 'Поле обов\'язково для заповнення!';

Використання в контролері:

$this->load->language('module/mymodule');
$data['text_add_cart'] = $this->language->get('text_add_cart');

У Twig-шаблоні:

<button>{{ text_add_cart }}</button>

Мультимовний контент товарів

Кожен товар має опис на кожній мові. У базі даних зберігається в таблиці oc_product_description з полем language_id:

SELECT pd.name, pd.description, pd.meta_title, pd.meta_description, l.name as language
FROM oc_product_description pd
JOIN oc_language l ON pd.language_id = l.language_id
WHERE pd.product_id = 123;

У формі редагування товару — вкладки по мовам:

Product Edit → Вкладка "Data":
  [Українська]  → назва, опис, метатеги українською
  [English]     → name, description, meta tags in English
  [Російська]   → название, описание, мета-теги по-русски

Якщо переклад відсутній для мови — OpenCart відображає опис мови за замовчуванням.

SEO-URL для мультимовності

Для кожної мови — окремий SEO-slug:

-- Українська URL
INSERT INTO oc_seo_url (store_id, language_id, key, value, keyword)
VALUES (0, 1, 'product_id', '123', 'chorne-ofisne-krislo');

-- Англійська URL
INSERT INTO oc_seo_url (store_id, language_id, key, value, keyword)
VALUES (0, 2, 'product_id', '123', 'black-office-chair');

Або через UI: Product Edit → SEO Tab → Per-language URL keywords.

Для коректної мультимовної SEO-структури — встановити hreflang-теги. OpenCart не робить це автоматично, потрібен кастомний код або розширення:

{# У header.twig додаємо hreflang #}
{% for lang in languages %}
<link rel="alternate"
      hreflang="{{ lang.code }}"
      href="{{ lang.href }}">
{% endfor %}
<link rel="alternate" hreflang="x-default" href="{{ canonical }}">

Дані для languages передаються з контролера через модифікацію header-контролера.

Перемикач мови

У шаблоні — через сніппет common/language:

{# У header.twig #}
<div class="language-switcher">
    {% for language in languages %}
    <a href="{{ language.href }}" class="{% if language.code == language_code %}active{% endif %}">
        <img src="{{ language.image }}" alt="{{ language.name }}">
        {{ language.name }}
    </a>
    {% endfor %}
</div>

languages — змінна, передавана з контролера common/header. Вона вже містить список доступних мов з href для поточної сторінки.

Налаштування валют

Додавання валюти:

System → Localization → Currencies → Add Currency
→ Currency Title: Українська гривня
→ Code: UAH
→ Symbol Left: (пусто)
→ Symbol Right: ₴
→ Decimal Places: 2
→ Decimal Point: ,
→ Thousand Point: (пробіл)
→ Value: 1  (курс до базової валюти)
→ Status: Enabled
→ Default: (якщо UAH — основна валюта магазину)

Приклад для трьох валют магазину, орієнтованого на СНГ:

Валюта Код Символ Decimals Default
Українська гривня UAH 2 Так
Російський рубль RUB 2 Ні
Американський долар USD $ 2 Ні

Автооновлення курсів:

OpenCart підтримує автооновлення через кілька джерел. За замовчуванням використовується ECB (Європейський центральний банк), що незручно для UAH.

Конфігурація джерела курсів:

System → Settings → Local
→ Currency Auto Update: ECB (вибрати джерело)

Ручне оновлення:

System → Localization → Currencies → Update Currency Rates

Для автоматичного оновлення по розпису — cron:

# Щодня о 9:00
0 9 * * * /usr/bin/php /var/www/myshop/index.php \
    route=cron/currency \
    cron_token=YOUR_CRON_TOKEN

Або кастомний скрипт з парсингом API НБУ:

// shell/update_currencies.php
$nbu = json_decode(file_get_contents('https://api.privatbank.ua/p24api/pubinfo?json&exchange&coursid=5'), true);
$rates = array_column($nbu, 'sale', 'ccy');

$pdo = new PDO("mysql:host=localhost;dbname=opencart", 'user', 'pass');

foreach (['USD', 'EUR', 'RUB'] as $currency) {
    if (isset($rates[$currency])) {
        $stmt = $pdo->prepare(
            "UPDATE oc_currency SET value = ?, date_modified = NOW() WHERE code = ?"
        );
        $stmt->execute([1 / $rates[$currency], $currency]); // UAH як базова
    }
}

Запуск через cron, результат — актуальні курси в базі.

Перемикач валюти

Перемикач працює через форму POST до common/currency:

{# У header.twig #}
<div class="currency-switcher">
    {% for currency in currencies %}
    <form action="{{ action_currency }}" method="post">
        <input type="hidden" name="code" value="{{ currency.code }}">
        <input type="hidden" name="redirect" value="{{ redirect }}">
        <button type="submit" class="{% if currency.code == currency_code %}active{% endif %}">
            {{ currency.symbol_left }}{{ currency.symbol_right }} {{ currency.code }}
        </button>
    </form>
    {% endfor %}
</div>

Або через AJAX для зміни без перезавантаження сторінки:

document.querySelectorAll('[data-currency]').forEach(btn => {
    btn.addEventListener('click', async function() {
        const code = this.dataset.currency
        await fetch(actionCurrencyUrl, {
            method: 'POST',
            body: new URLSearchParams({ code, redirect: window.location.href })
        })
        window.location.reload()
    })
})

Мультивалютні ціни у каталозі

OpenCart зберігає всі ціни в базовій валюті і пересчитує на льоту через $this->currency->format(). Це означає, що при зміні курсу всі відображені ціни оновлюються автоматично.

Якщо потрібні зафіксовані «гарні» ціни в кожній валюті (наприклад, 999 UAH замість 998,73) — це реалізується через кастомний total модуль або через поля на рівні товару з переопреденням методу розрахунку ціни.

Мультимагазин: різні налаштування на різних доменах

OpenCart підтримує кілька магазинів зі спільною базою даних:

System → Settings → Add Store
→ Store Name: Магазин для Росії
→ URL: https://myshop.ru/
→ Default Language: Russian (ru-ru)
→ Default Currency: RUB

Кожен магазин (store_id) має свої налаштування мови, валюти, шаблону та асортименту. Товари прив'язуються до конкретного магазину через вкладку «Links» у редакторі товару.

У nginx — один server-конфіг, один PHP-файл, а контент визначається за HTTP_HOST:

server {
    server_name myshop.ua myshop.ru;
    root /var/www/myshop/public_html;
    # OpenCart сам визначає store_id за доменом
}

Типові проблеми

Ціни у каталозі не оновилися після зміни курсу. Причина — кеш сторінок. Рішення: очистити кеш:

System → Tools → Cache → Clear

Або програмно:

php index.php route=cron/cache cron_token=TOKEN

SEO-URL дублюються для різних мов. Кожна запись в oc_seo_url повинна мати унікальну комбінацію (store_id, language_id, keyword). Перевірити:

SELECT keyword, COUNT(*) FROM oc_seo_url
GROUP BY keyword HAVING COUNT(*) > 1;

Переключення мови веде на головну. Потрібно передавати redirect з поточною URL при переключенні. У стандартному контролері мови це реалізовано, але деякі теми видаляють приховане поле з форми.

Терміни налаштування

  • Установка мов (2–3 мови) + переклад товарів: 1–2 дні
  • SEO-URL для кожної мови + hreflang: 1 день
  • Налаштування валют + автооновлення курсів (НБУ/ЦБ РФ): 0,5–1 день
  • Перемикачі мови та валюти у шаблоні: 0,5 дня
  • Мультимагазин (різні домени): +1–2 дні

Разом при готовій темі: 2–4 дні.