Сайт на двух языках — это не роскошь, а необходимость. Но когда дело доходит до реализации в Yii2, многие разработчики начинают нервно листать документацию. Знакомая ситуация? Давайте разберёмся, как сделать мультиязычность правильно и без боли.
Зачем вообще нужна мультиязычность и с чем её едят
Мультиязычность — это не просто перевод кнопок. Это целая система, которая включает:
- Перевод статического текста (заголовки, кнопки, сообщения)
- Перевод контента из базы данных (статьи, товары, описания)
- Локализацию URL (site.com/ru/about и site.com/en/about)
- Форматирование дат, чисел и валют
Если вы думаете, что достаточно захардкодить массив с переводами, вы сильно ошибаетесь. Yii2 предлагает мощный инструментарий, который многие просто не замечают.
Настройка базовых компонентов: язык, URL и сессии
Первое, что нужно сделать — настроить компонент i18n и urlManager. Это фундамент, без которого всё остальное развалится.
Откройте файл конфигурации config/web.php и добавьте следующие настройки:
'components' => [
'language' => 'ru', // язык по умолчанию
'sourceLanguage' => 'en', // язык исходного кода
'i18n' => [
'translations' => [
'app*' => [
'class' => 'yii\i18n\PhpMessageSource',
'basePath' => '@app/messages',
'sourceLanguage' => 'en',
'fileMap' => [
'app' => 'app.php',
'app/error' => 'error.php',
],
],
],
],
'urlManager' => [
'enablePrettyUrl' => true,
'showScriptName' => false,
'rules' => [
'//' => '/',
'' => 'site/index',
],
],
],
Теперь создайте папку messages в корне проекта и внутри неё — подпапки ru и en. В каждой будет файл app.php с переводами:
// messages/ru/app.php
return [
'Hello' => 'Привет',
'Welcome to our site' => 'Добро пожаловать на наш сайт',
'Read more' => 'Читать далее',
];
Теперь в представлениях можно использовать:
= Yii::t('app', 'Hello') ?>
Переключение языка: компонент LanguageSelector
Нужно, чтобы пользователь мог переключить язык. Создадим простой компонент:
namespace app\components;
use Yii;
use yii\base\Component;
class LanguageSelector extends Component
{
public function init()
{
parent::init();
$this->setLanguage();
}
private function setLanguage()
{
$session = Yii::$app->session;
$request = Yii::$app->request;
if ($request->get('lang')) {
$lang = $request->get('lang');
if (in_array($lang, ['ru', 'en'])) {
$session->set('language', $lang);
}
}
$language = $session->get('language', 'ru');
Yii::$app->language = $language;
}
}
Подключите его в конфигурации как компонент languageSelector и добавьте в bootstrap. Теперь при переходе по ссылке ?lang=en язык переключится и запомнится в сессии.
В представлении можно сделать простые ссылки:
Русский
English
Мультиязычные модели: перевод контента из базы
Самый сложный момент — перевод данных из БД. Есть два подхода:
| Подход | Плюсы | Минусы |
|---|---|---|
| Отдельные таблицы для каждого языка | Простота запросов, гибкость | Дублирование структуры, сложность миграций |
| Одна таблица с полями title_ru, title_en | Простота миграций | Раздувание таблицы, сложность при добавлении языков |
| Отдельная таблица переводов (EAV) | Гибкость, легко добавлять языки | Сложные запросы, нужен доп. код |
Я рекомендую третий вариант с использованием поведения TranslateBehavior из пакета creocoder/yii2-translateable или собственной реализации. Вот пример собственного поведения:
namespace app\behaviors;
use yii\base\Behavior;
use yii\db\ActiveRecord;
use app\models\ArticleTranslation;
class TranslateBehavior extends Behavior
{
public $translationModel = ArticleTranslation::class;
public $translationAttributes = ['title', 'content'];
public function getTranslation($language = null)
{
$language = $language ?: Yii::$app->language;
return $this->translationModel::findOne([
'article_id' => $this->owner->id,
'language' => $language,
]);
}
public function __get($name)
{
if (in_array($name, $this->translationAttributes)) {
$translation = $this->getTranslation();
return $translation ? $translation->$name : $this->owner->$name;
}
return parent::__get($name);
}
}
Теперь в модели Article достаточно подключить это поведение, и обращение к $article->title автоматически вернёт перевод для текущего языка.
Локализация дат и чисел: не забываем про мелочи
Даты и числа в разных странах форматируются по-разному. В Yii2 за это отвечает компонент formatter. Настройте его в конфиге:
'formatter' => [
'dateFormat' => 'dd.MM.yyyy',
'decimalSeparator' => ',',
'thousandSeparator' => ' ',
'currencyCode' => 'RUB',
],
Для английского языка можно переопределить настройки динамически:
if (Yii::$app->language === 'en') {
Yii::$app->formatter->dateFormat = 'MM/dd/yyyy';
Yii::$app->formatter->decimalSeparator = '.';
Yii::$app->formatter->thousandSeparator = ',';
Yii::$app->formatter->currencyCode = 'USD';
}
LocaleHelper, который будет автоматически применять настройки форматтера в зависимости от языка. Это избавит от дублирования кода.
Автоматизация перевода: используем консольные команды
Чтобы не искать вручную все строки для перевода, Yii2 предоставляет команду message/extract. Запустите её из консоли:
./yii message/extract @app/config/i18n.php
Создайте файл i18n.php с настройками:
return [
'sourcePath' => __DIR__ . '/../',
'messagePath' => __DIR__ . '/../messages',
'languages' => ['ru', 'en'],
'translator' => 'Yii::t',
'sort' => false,
'overwrite' => true,
'removeUnused' => false,
'markUnused' => true,
'except' => [
'.svn',
'.git',
'.gitignore',
'.gitkeep',
'.hgignore',
'.hgkeep',
'/messages',
'/vendor',
],
'format' => 'php',
];
После выполнения команды в папках messages/ru и messages/en появятся файлы со всеми найденными строками. Останется только перевести значения.
Что в итоге: чек-лист мультиязычного сайта на Yii2
Подведём итоги. Чтобы ваш сайт заговорил на нескольких языках, нужно:
- Настроить компоненты
i18n,urlManagerиformatter - Создать систему переключения языка через сессии
- Организовать хранение переводов контента в базе данных
- Использовать консольные команды для извлечения строк
- Не забывать про локализацию дат, чисел и валют
Мультиязычность — это не страшно, если подойти к ней системно. Yii2 даёт все инструменты, а ваша задача — правильно их приготовить. Главное — не хардкодить переводы и следить за чистотой кода.
Теперь вы знаете, как сделать сайт на Yii2 мультиязычным. Осталось только применить знания на практике. Удачи в разработке!
