Skip to content

Latest commit

 

History

History
311 lines (209 loc) · 11.7 KB

translate.md

File metadata and controls

311 lines (209 loc) · 11.7 KB

Интернационализация / Переводы

Компонент интернационализации работает на основе symfony/translation с некоторыми расширениями и загрузкой словарей из модулей

Словари

Словарь - это папка, имя которой является именем словаря (домена в нотации symfony/translation), которая содержит набор файлов по локалям, где имя файла - это наименование локали, а содержимое - правила перевода данного словаря для данной локали.

Пример:

- Test
    - messages
        - main
            - ru.php
            - en.php
        - custom
            - ru.php
            - en.php

По-умолчанию доступна работа с файлами с расширениями: php, json, po, mo

Словари располагаются в модулях и в приложении. Словари в приложении имеют высокий приоритет, словари в модулях - низкий.

Словари в модулях

Словари в модулях расположены в папке messages от корня модуля. Например, словари модуля Test должны располагаться в папке app/Modules/Test/messages.

К имени словарей в модулях автоматически добавляется префикс в виде имени модуля.

Пример расположения словаря main в модуле Test:

- Test
    - messages
        - main
            - ru.php
            - en.php

Полное имя словаря будет таким: Test.main, соответственно, вызвать перевод с из данного словаря можно следующим образом

Phact::app()->translate->t("Test.main", "Some key")

Файлы правил перевода по локалям могут быть расположены непосредственно в папке messages:

- Test
    - messages
        - ru.php
        - en.php

В этом случае полное имя словаря будет таким: Test.messages и вызвать перевод можно будет как с указанием имени словаря:

Phact::app()->translate->t("Test.messages", "Some key")

так и с указанием только имени модуля:

Phact::app()->translate->t("Test", "Some key")

Словари в приложении

Словари в приложении организованы таким же образом как и в модулях, за исключением того, что к их имени не добавляются никакие префиксы.

Словари приложения расположены в папке app/messages

Пример расположения словаря main в приложении:

- app
    - messages
        - main
            - ru.php
            - en.php

Полное имя словаря будет таким: main, соответственно, вызвать перевод с из данного словаря можно следующим образом

Phact::app()->translate->t("main", "Some key")

Словари в приложении так же позволяют перекрыть стандартные словари (*Phact.**) и словари модулей. Для примера перекроем словарь модуля Test: Test.messages

- app
    - messages
        - Test.messages
            - ru.php
            - en.php

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

Компонент интернационализации

Компонент расположен по адресу Phact::app()->translate

Конфигурирование

Пример конфигурации:

...
'translate' => [
    'class' => \Phact\Translate\Translate::class,
    'default' => 'ru',
    'locales' => [
        'ru' => 'Русский',
        'en' => 'English'
    ],
    'localeDetector' => function () {
        ...
    }
],
...

Основные настройки:

localeDetector - детектор локали. Указывается либо тип callable, либо класс объекта с имплементированным интерфейсом \Phact\Translate\LocaleDetector. Идентифицирует локаль и возвращает ее наименование в строковом формате.

default - локаль по-умолчанию. Применяется при отсутствии localeDetector или при возвращении им пустого значения

locales - список локалей. Внутри компонента не используется, оставлено для удобства разработчика.

Основные методы

setLocale($localeName) - устанавливает текущую локаль

getLocale() - получает текущую локаль

getTranslator() - получает объект \Symfony\Component\Translation\Translator

t - метод для получения перевода

Работа с переводом

Метод для получения перевода может использоваться в двух сценариях:

  1. Для обычного перевода строки
  2. Для перевода с плюрализацией

Для обоих сценариев первые два параметра остаются одинаковыми - это имя словаря и ключ в словаре перевода. Причем, если передать только один параметр - то он будет считатся ключом, а домен будет выбираться по-умолчанию.

А теперь рассмотрим применение подробнее.

Простой перевод строки

И сразу с примеров. Получение значения по ключу Some key из словаря Test.main.

Phact::app()->translate->t('Test.main', 'Some key')

Тут всё просто.

Перевод строки с плюрализацией

Получение плюрализированного значения по ключу element|elements из словаря Test.main со значением 2.

Phact::app()->translate->t('Test.main', 'element|elements', 2)

В данном случае компонент перевода не просто сделает перевод строки, но и по правилу определения плюрализации для нашей локали выберет из значения, разделенного символом "|" нужный сегмент.

Например, для английского языка он выдаст значение "elements".

А если указать соответствующее значение в словаре для русского языка

[
    ...
    'elements|elements' => 'элемент|элемента|элементов'
    ...
]

то значением будет "элемента"

Дополнительные параметры метода t

Дополнительно оба сценария могут принимать:

  1. Списки замен
  2. Имя локали

Списки замен

Иногда бывает достаточно удобно (и даже правильно) вводить динамические параметры в наши строки с переводом. Например вместо следующей конструкции:

Phact::app()->translate->t("Test.main", "Hello, ") . $username . Phact::app()->translate->t("Test.main", ", have a nice day!");

Можно применять следующую:

Phact::app()->translate->t("Test.main", "Hello, %username%, have a nice day!", ['%username%' => $username]);

Для строк с плюрализацией один элемент в списке замен всегда присутствует - это %count%, который содержит значение, которое вы передали для плюрализации.

Пример:

Phact::app()->translate->t('Test.main', '%count% element|%count% elements', 2)

Но и для перевода с плюрализацией доступны обычные замены.

Указание локали

Последним параметром в обоих сценариях можно передать локаль форсированно, тогда перевод будет осуществлен не с учетом локали установленной в компоненте, а с учетом переданной локали в параметре.

Перевод в php-коде

Для удобства применения перевода в коде существует trait \Phact\Translate\Translator, который добавляет к вашему классу метод ::t, который является чуть улучшенным алиасом метода Phact::app()->translate->t.

Улучшение заключется в том, что если метод применяется к классу модуля у которого применен trait \Phact\Helpers\ClassNames или существует метод ::getModuleName (например у всех моделей в модуле), то для них будет установлен словарь по-умолчанию: "{$moduleName}".

Пример:

<?php

namespace Modules\Test\Models;

use Phact\Orm\Fields\CharField;
use Phact\Orm\Model;
use Phact\Translate\Translator;

class Blogger extends Model
{
    use Translator;
    
    public static function getFields()
    {
        return [
            'name' => [
                'class' => CharField::class,
                'label' => self::t("Blogger name")
            ]
        ];
    }
}

В данном примере обращение self::t("Blogger name") будет равно обращению self::t("Test", "Blogger name"), так как имя модуля в качестве словаря подставится автоматически.

К тому же использование trait \Phact\Translate\Translator чуть более безопасно, так как содержит проверку на присутствие компонента translate в приложении.

Перевод в шаблонизаторе

Для удобства перевода в шаблонизаторе добавлены функция (для непосредственного вывода данных) и accessor-функция (для получения результата перевода в переменную).

Примеры:

{t "Test" "Module test"}

{t "Test.main" "test"}

{t "Test" "%count% item|%count% items" 2}

{$.t("Test.main", "test")}

{set $translated = $.t("Test" "%count% item|%count% items", 1)}