Студия разработки сайтов и приложений

Netspark.ru

Локализация в OctoberCMS

На днях совершил над собой титаническое усилие и добавил-таки своему Netspark.ru английскую версию. Учитывая, что это по сути одностраничник (ну, плюс 404 и «Сайт на обслуживании») — можно было бы тупо скопировать и поменять текстики на английские. Тем более английскую версию поставил на другой домен. Но все же чтобы фронт-энд был одинаковый в обеих версиях — мало ли там, добавить чего, поменять — решил использовать возможности локализации. О чем и расскажу немного.

Локализация в OctoberCMS — примерно такая же, как в Laravel. Есть файлы с локализацией, например lang.php, из них возвращаются массивы, примерно так:

return [
    'messages' => [
        'my_message' => 'Hello world',
    ],
];

После чего используется фильтр trans в твиге, где обращение к строке происходит как author.pluginname::lang.messages.mymessage. Author и pluginname — это имя автора и плагина, чтобы было ясно, откуда брать строки. Соответственно, файлы локализации должны жить в плагинах.

Это нормально, если проект не совсем примитивный и в нём есть кастомный плагин для всяких там дополнений и расширений. Но в рассматриваемом случае проект совсем примитивный и кастомных плагинов в нём нет, соответственно, хранить переводные строки негде. В таком случае нужно использовать плагин Translate. Если он установлен, хранить переводы можно прямо в theme.yaml используемой фронт-энд-темы. Заинклудить отдельный ямл с переводами тоже можно, да.

В файле строки будут храниться вот так:

translate:
    en:
        nav.portfolio: 'Our works'
        nav.services: 'Services'
    ru:
        nav.portfolio: 'Наши работы'
        nav.services: 'Услуги'

А обращаться к строчкам во фронт-энде можно с помощью фильтра твига _, вот так:

{{ 'nav.portfolio'|_ }}

То есть даже неймспейс никакой соблюдать не надо.

В фильтр перевода можно передавать параметры для подстановки:

{{ 'There are :works works in portfolio'|_({works: 1000}) }}

Естественно, строчку There are :works works in portfolio тоже можно положить в ямл и заменить дескриптором.

Помимо фильтра перевода _, есть и фильтр __, вызывающий transchoice() и помогающий в правильном склонении множественных чисел.

Чтобы строки из yaml-файла попали в систему, нужно их сначала обнаружить плагином Translate. Для этого со страницы переводов нужно запустить сканирование сообщений и затем почистить кэш.

К слову, если пользоваться плагином Translate, хранить строки в yaml-файле вообще необязательно. Если подать любую строку во фронт-энде на фильтр перевода, она может быть отсканирована и переведена через админку плагина. Примерно как функция t() в Друпале — засунул в неё что-нибудь, и это что-нибудь стало можно перевести. Но что еще интересно, в отличие от Друпала, где системный язык всегда английский и мы переводим с него, в OctoberCMS с плагином Translate дефолтный язык — действительно дефолтный. То есть мы можем сделать сайт на русском, сделать русский дефолтным, и переводить строки с русского на французский, или китайский, вообще без какого-либо упоминания английского.

Что еще можно сказать. Как видно из скриншота выше, плагин позволяет экспортировать переводы в и импортировать из csv-файлов (аналогично импорту-экспорту моделей).

Напоследок приведу пример определения текущей локали в системе. Я просто добавил обработчик onStart() в лейаут, и страницам, использующим этот лейаут, стали доступны переменные switchLocaleName, switchLocaleFlag и switchLocaleLink.

use RainLab\Translate\Classes\Translator;
protected $translator;

function onStart() {
    $this->translator = Translator::instance();
    $switchLocale = ($this->translator->getLocale() == 'ru') ? 'en' : 'ru';
    $this['switchLocaleName'] = ($switchLocale == 'ru') ? 'Русская версия' : 'English version';
    $this['switchLocaleFlag'] = 'assets/img/flags/' . $switchLocale . '.svg';
    $this['switchLocaleLink'] = ($switchLocale == 'ru') ? 'https://netspark.ru' : 'https://netspark.pro';
}

Лично мне это пригодилось, чтобы построить свой переключатель языков, который направляет на другой домен, вместо изменения языка в URL.

Комментарии