Решил поиграться с настройкой мультиязычности в Magento 2.4.
Для начала определился, что хочу сделать URL вот такого вида
- /au/en - Австралия, английский
- /nz/en - Новая Зеландия, английский
- /nz/mi - Новая Зеландия, Маори
- /us/en - США, Английский
- /us/es - США, Испанский
Сделать это было бы довольно просто, если бы Store View Code мог содержать слеш, однако это не так. Можно конечно задать Store View Code вот так "us_en" и получить url вида "http://m242.sv/us_en", но это не красиво.
Везде далее будет использоваться мой локальный домен "m242.sv", вам надо использовать свой
Кроме того, Store View Code должен быть уникальным, т.е. сделать конфигурацию вида
- au/en
- Base Url: site.com/au/
- Store Code: au
- Store View Code: en
- nz/en
- Base Url: site.com/nz/
- Store Code: nz
- Store View Code: en
так же не получится, т.к. Store View Code в обоих случаях "en".
Разрулить такую ситуацию помогают обычные папки и реврайты в nginx.
Настройка Сторов
Admin > Settings > All Stores
Создаем вебсайт, сторы и стор вью по такой схеме
- au/en
- Store Code: au
- Store View Code: au_en
- Store Code: au
- nz/en, nz/mi
- Store Code: nz
- Store View Code: nz_en
- Store View Code: nz_mi
- Store Code: nz
- us/en, us/mi
- Store Code: us
- Store View Code: us_en
- Store View Code: us_mi
- Store Code: us
Настройка Base URL
Admin > Stores > Configuration > [Выбрать Scope] > General > Web > Base URLs
Меняем Base Url и Base Url Link
- Scope: Default config
- Base URL: http://m242.sv/
- Base Link URL: http://m242.sv/
- Base URL for Static View Files: http://m242.sv/static/
- Base URL for User Media Files: http://m242.sv/media/
- AU English Store View
- Base URL: http://m242.sv/au/en
- Base Link URL: http://m242.sv/au/en
- NZ English Store View
- Base URL: http://m242.sv/nz/en
- Base Link URL: http://m242.sv/nz/en
- NZ Maori Store View
- Base URL: http://m242.sv/nz/mi
- Base Link URL: http://m242.sv/nz/mi
- US English Store View
- Base URL: http://m242.sv/us/en
- Base Link URL: http://m242.sv/us/en
- US Espanol Store View
- Base URL: http://m242.sv/us/es
- Base Link URL: http://m242.sv/us/es
Настройка Nginx
В файл конфигурации Nginx-а, добавляем реврайты в корневую секцию location
location / {
try_files $uri $uri/ /index.php$is_args$args;
location /au/en/ {
if (!-e $request_filename) {
rewrite ^.*$ /au/en/index.php last;
}
}
location /nz/en/ {
if (!-e $request_filename) {
rewrite ^.*$ /nz/en/index.php last;
}
}
location /nz/mi/ {
if (!-e $request_filename) {
rewrite ^.*$ /nz/mi/index.php last;
}
}
location /us/en/ {
if (!-e $request_filename) {
rewrite ^.*$ /us/en/index.php last;
}
}
location /us/es/ {
if (!-e $request_filename) {
rewrite ^.*$ /us/es/index.php last;
}
}
}
А так же в location обрабатывающий php скрипты
# PHP entry point for main application
location ~ ^/(index|au/en/index|nz/en/index|nz/mi/index|us/en/index|us/es/index|get|static|errors/report|errors/404|errors/503|health_check)\.php$ {
...
Index файлы в Magento
Создаем соответствующие индекс файлы в которых и укажем какой Store View Code нужно использовать
- pub/au/en/index.php
- pub/nz/en/index.php
- pub/nz/mi/index.php
- pub/us/en/index.php
- pub/us/es/index.php
Содержимое вот такое
<?php
/**
* Public alias for the application entry point
*
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
use Magento\Framework\App\Bootstrap;
use Magento\Framework\App\Filesystem\DirectoryList;
try {
require __DIR__ . '/../../../app/bootstrap.php';
} catch (\Exception $e) {
echo <<<HTML
<div style="font-family:Arial;">
<div style="margin:25px auto;">
<h3 style="color:red;">Autoload error</h3>
</div>
<p>{$e->getMessage()}</p>
</div>
HTML;
exit(1);
}
$params = $_SERVER;
$params[Bootstrap::INIT_PARAM_FILESYSTEM_DIR_PATHS] = array_replace_recursive(
$params[Bootstrap::INIT_PARAM_FILESYSTEM_DIR_PATHS] ?? [],
[
DirectoryList::PUB => [DirectoryList::URL_PATH => ''],
DirectoryList::MEDIA => [DirectoryList::URL_PATH => 'media'],
DirectoryList::STATIC_VIEW => [DirectoryList::URL_PATH => 'static'],
DirectoryList::UPLOAD => [DirectoryList::URL_PATH => 'media/upload'],
]
);
$params[\Magento\Store\Model\StoreManager::PARAM_RUN_CODE] = 'au_en';
$params[\Magento\Store\Model\StoreManager::PARAM_RUN_TYPE] = 'store';
$bootstrap = \Magento\Framework\App\Bootstrap::create(BP, $params);
/** @var \Magento\Framework\App\Http $app */$app = $bootstrap->createApplication(\Magento\Framework\App\Http::class);
$bootstrap->run($app);
Тут в PARAM_RUN_CODE нужно указать соответсвующий Store View Code, т.е. один из: au_en, nz_en, nz_mi, us_en, us_es.
Отключение добавления Store View Code в URL
Admin > Stores > Configuration > Scope:Default Config > General > Web > Url Options
Нужно установить "Add Store Code to Urls = No" если это не так
Перезагрузка Nginx и чистка кешей
Перезапускаем nginx
sudo nginx -t
sudo nginx -s reload
Чистим кеши Magento и при необходимости Redis-а
php bin/magento c:f
redis-cli flushall
В случае странных редиректов по типу переходите на au/en, а открывается us/en, попробуйте почистить куки в браузере, т.к. Store Switcher ставит куку, которую система использует для определения дефолтного стора. Эта логика находится тут: vendor/magento/module-store/Model/StoreResolver.php [method: getCurrentStoreId]
Проверка
Переходим на витрину магазина и видим, что в футере появился свитчер сторов
И для сторов у которых больше 1 стор вью, появляется переключатель языков в в шапке сайта
Дальнейшая настройка локалей, валют и всего остального делается как обычно 🙂