Налаштування мультиязичності та мультивалютності 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 дні.







