Роберт

Backend-разработчик
Пишу о программировании, музыке, книгах и жизни

Главная

Интернационализация Yii2 а-ля Laravel

Yii::t('app', 'message') -> trans('app.category.sub_category.message')

Переопределяем метод PhpMessageSource::loadMessages()


namespace app\components;

use Yii;

class PhpMessageSource extends \yii\i18n\PhpMessageSource
{
    protected function loadMessages($category, $language)
    {
        $newCategory = $category;
        $keys = [];
        if (false !== strpos($category, '.')) {
            $keys = explode('.', $category);
            $newCategory = array_shift($keys);
        }
        $messageFile = $this->getMessageFilePath($newCategory, $language);
        $messages = $this->loadMessagesFromFile($messageFile);

        if (false !== strpos($category, '.')) {
            $messages = $this->searchKey($messages, $keys);
        }

        $fallbackLanguage = substr($language, 0, 2);
        $fallbackSourceLanguage = substr($this->sourceLanguage, 0, 2);

        if ($language !== $fallbackLanguage) {
            $messages = $this->loadFallbackMessages($newCategory, $fallbackLanguage, $messages, $messageFile);
        } elseif ($language === $fallbackSourceLanguage) {
            $messages = $this->loadFallbackMessages($newCategory, $this->sourceLanguage, $messages, $messageFile);
        } else {
            if ($messages === null) {
                Yii::warning("The message file for category '$newCategory' does not exist: $messageFile", __METHOD__);
            }
        }

        return (array)$messages;
    }

    private function searchKey($messages, $keys)
    {
        $keyCurrent = array_shift($keys);

        if (array_key_exists($keyCurrent, $messages) && is_array($messages[$keyCurrent])) {
            if (!$keys) {
                return $messages[$keyCurrent];
            }

            return $this->searchKey($messages[$keyCurrent], $keys);
        }
    }
}

В конфиге приложения для компонента i18n указываем наш класс:


'components' => [
    ...
    'i18n' => [
            'translations' => [
                '*' => [
                    'class' => \app\components\PhpMessageSource::class,
    ...

Добавляем глобальную функцию, которая будет оберткой для стандартного вызова метода Yii::t()


function trans(string $message)
{
    return Yii::t($message, substr(strrchr($message, '.'), 1));
}

Теперь в файлах переводов можно указывать переводы с категориями


'access_denied' => 'Доступ закрыт',
'category' => [
    'sub_category' => [
        'message' => 'Сообщение',
    ],
],

Роберт Фатхуллин

Статья Роберт Фатхуллин

Web-разработчик