Перевод строк
Drupal умеет показывать сайт на нескольких языках. Чтобы надписи модуля можно было перевести, их не пишут обычными строками, а пропускают через функцию перевода. Она ищет перевод для текущего языка и возвращает его, а если перевода нет — исходный текст.
Функция t
В классах, унаследованных от ControllerBase, FormBase и BlockBase, есть метод $this->t():
// web/modules/custom/blog/src/Controller/BlogController.php
public function about(): array
{
return [
'#markup' => $this->t('Блог о разработке на Drupal.'),
];
}Страница /blog/about выглядит как раньше, но теперь эта строка появится в списке для перевода. В функциях файла blog.module используют функцию t() без $this.
Подстановки
Изменяемые части не вклеивают в строку, а передают вторым аргументом:
// web/modules/custom/blog/src/Controller/BlogController.php
$text = $this->t('Автор: @name, статей: @count', [
'@name' => $authorName,
'@count' => 12,
]);Переводчик получит строку с метками и сможет поменять порядок слов. Вид метки определяет обработку значения.
| Метка | Что происходит со значением |
|---|---|
@name | Экранируется |
%name | Экранируется и выделяется курсивом |
:url | Экранируется и проверяется как адрес — для атрибута href |
Множественное число
// web/modules/custom/blog/src/Controller/BlogController.php
$text = $this->formatPlural($count, '1 статья', '@count статей');Первый аргумент — число, второй — форма для одного, третий — для многих. В языках с несколькими формами, как в русском, переводчик задаст их все в интерфейсе перевода.
Строки вне методов
В атрибутах плагинов и других местах, где $this->t() недоступен, создают объект напрямую:
// web/modules/custom/blog/src/Plugin/Block/LatestArticlesBlock.php
use Drupal\Core\StringTranslation\TranslatableMarkup;
$label = new TranslatableMarkup('Свежие статьи');t() возвращает такой же объект TranslatableMarkup. Перевод выполняется не сразу, а когда объект превращается в строку при выводе.
В шаблонах Twig
{# web/modules/custom/blog/templates/blog-card.html.twig #}
<a href="{{ path('blog.list') }}">{{ 'Все статьи'|t }}</a>
<p>{{ 'Автор: @name'|t({'@name': author}) }}</p>Фильтр t делает то же, что функция в PHP. Подстановки передаются в скобках.
В файлах YAML
Значения title и description в файлах blog.routing.yml, blog.links.menu.yml, blog.permissions.yml и name в blog.info.yml переводятся автоматически — оборачивать их не нужно.
Где вводят перевод
Включите модули ядра Language и Interface Translation и добавьте язык в разделе «Конфигурация → Регион и язык → Языки». Строки модуля переводят на странице «Перевод интерфейса», адрес /admin/config/regional/translate. Строка появляется в списке после того, как хотя бы раз была выведена на сайте.
В настоящих проектах исходные строки принято писать на английском: Drupal считает английский языком кода, а русский текст добавляют как перевод. В этом курсе строки написаны по-русски только для наглядности.
Частая ошибка
Нельзя передавать в t() переменную или склеенную строку: t($message) или t('Автор: ' . $name). Инструменты сбора строк читают код, не выполняя его, и такой текст не найдут, а для каждого имени получится отдельная строка без перевода. В t() передают только строку-константу, а изменяемые части — подстановками.