# Переводы модулей и общие сведения

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

В JohnCMS по умолчанию предустановлены несколько языков. В этом разделе мы разберемся как с ними работать и как переводить ваши модули на различные языки, которые вам нужны.

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

### Как сделать модуль мультиязычным?

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

#### Простой перевод фраз

```php
echo __('Hello World');
```

#### Множественное/единственное число

```php
echo n__('One apple', '%s apples', 5, 5);
```

В примере выше первым аргументом передается фраза в единственном числе. \
Вторым аргументом передается фраза во множественном числе. \
Третьим аргументом передается само число из-за которого будет приниматься решение какую фразу выбрать (если будет передано число 1, то выведется фраза One apple, если будет передано число 5, то будет выведено 5 apples).\
Четвертым и последующими аргументами передаются данные, которые будут заменены в строке для перевода. Например в указанной фразе %s будет заменено на число 5.

#### Перевод фраз в зависимости от контекста

```php
echo p__('placeholder', 'Login')
```

Часто есть необходимость в одном файле написать фразы, которые могут писаться на английском языке одинаково, а на другом языке по-разному в зависимости от контекста.\
Чтобы разделить такие фразы вы можете использовать функцию p\_\_(). Первым аргументом передается название контекста, а вторым передается фраза, которая будет переводиться.

#### Множественное/единственное число в зависимости от контекста

```php
echo np__('contextName', 'One apple', '%s apples', 5, 5);
```

#### Перевод из определенного домена

Домены при разработке модулей вам скорее всего не понадобятся, но всё же мы рассмотрим функции связанные с ними, а далее подробнее рассмотрим зачем они нужны.

```php
echo d__('domain', 'Hello World!');
```

#### Перевод из определенного домена и контекста

```php
echo dp__('domain', 'context', 'Hello World!');
```

#### Множественное/единственное число из определенного домена

```php
echo dn__('domain', 'One apple', '%s apples', 5, 5);
```

#### Множественное/единственное число из определенного домена и контекста

```php
echo dnp__('domain', 'context', 'domain', 'One apple', '%s apples', 5, 5);
```

### Структура

Для хранения переводов в модулях предусмотрена папка **locale**. Все переводы по умолчанию разбиваются по группам (так называемым доменам). Это позволяет избегать пересечения переводов из разных частей системы.\
По умолчанию все фразы модуля сгруппированы в группу с названием модуля без имени разработчика. (например для модуля **johncms/news** группа (домен) будет называться **news**).

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

Если же вы не наследуете базовый контроллер или вообще не используете контроллеры, вам необходимо добавить собственный домен и указать откуда загружать фразы переводов.\
Сделать это можно следующим образом:

```php
$translator = di(\Johncms\i18n\Translator::class);
$translator->addTranslationDomain('domainName', 'path_to_locale');
```

В примере выше в метод addTranslationDomain подается название домена и путь к папке в которой хранятся переводы.

### Создание переводов

Если в своем модуле вы обернули все фразы в функции описанные выше, то ваш модуль уже имеет один язык (английский) и готов к созданию переводов на другие языки.

В некоторых системах как и в очень ранних версиях JohnCMS контролировать наличие фраз в переводах нужно вручную. Это создает множество неудобств и порождает большое количество ошибок.

Для работы с переводами в JohnCMS используется [gettext](https://ru.wikipedia.org/wiki/Gettext). Почитать про него подробнее можете по ссылке на wikipedia, а мы рассмотрим как нам работать с этим в JohnCMS.

Для работы с gettext нам нужен базовый pot файл который содержит исходные фразы-ключи.\
Чтобы его создать давайте в корне проекта создадим файл **translate.xml** со следующим содержимым:

```xml
<?xml version="1.0"?>
<scanRuleset>
    <description>JohnCMS ruleset for PHP code scanner for gettext</description>

    <!-- My module -->
    <domain>
        <name>content</name>
        <target>modules/johncms/content/locale</target>
        <sourceDir>modules/johncms/content</sourceDir>
    </domain>
</scanRuleset>
```

В этом файле в теге domain > name указывается название домена (обычно это название модуля). В target - папка с переводами, а sourceDir - папка с исходными кодами вашего модуля (обычно это папка с самим модулем).

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

```bash
php johncms translate:scan
```

После выполнения этой команды в папке, которую вы указали в теге target появится файл с расширением .pot\
Для удобства перевода дальше вы можете открыть этот файл в программе Poedit [https://poedit.net](https://poedit.net/) и следуя инструкциям по работе с программой выполнить перевод. Если коротко, то добавляете язык на который хотите перевести и выполняете перевод.&#x20;

Все переведенные файлы сохраняйте в папку из которой вы открыли .pot файл.

Всё что дельше от вас потребуется, это сконвертировать перевод в php массив. Для этого выполните следующую команду:

```bash
php johncms translate:generate
```

После выполнения этой команды появится файл с кодом языка и расширением .lng.php\
На этом перевод завершен и если вы откроете модуль в браузере, вы увидите перевод фраз, который выполнили.
