{{% minver v="1.7.6" title="true" %}}
Новая система перевода модулей основана на новой системе, введенной в PrestaShop 1.7 для ядра и родных модулей. Она нацелена на гармонизацию систем перевода во всем PrestaShop, обеспечивая при этом обратную совместимость.
{{% notice info %}} Эта функция доступна только для PrestaShop 1.7.6 и выше. Если вам нужно поддерживать более старые версии, смотрите [Классическую систему перевода]({{< ref "classic-system" >}}). {{% /notice %}}
Словарь
- Фраза – Строка, которую вы можете захотеть перевести.
- Домен перевода – Контекстная группа фраз, которая позволяет перевести данную фразу по-разному в зависимости от контекста, в котором она появляется.
Как это работает
Аналогично классической системе, новая система перевода работает в два этапа.
1. Функции перевода используются для отображения фраз вашего модуля на другом языке
PrestaShop предоставляет функции, которые позволяют PHP-файлам и шаблонам Smarty/Twig отображать переведенные фразы. Используя список источников перевода (включая файлы словарей из классического перевода), модуль может использовать эту функцию для отображения фразы на другом языке во время выполнения.
{{< figure src="../img/new-translation-system.png" title="Как фразы переводятся во время выполнения" >}}
2. Создание словарей модулей
Страница Переводов в админ-панели (Международное > Переводы > Изменить переводы) используется для создания словарей модулей. Она извлекает фразы модуля, анализируя исходный код модуля, затем проверяет список источников для составления списка переводов и, наконец, отображает форму, которая позволяет вам настроить или завершить эти переводы на выбранном языке. После сохранения эта информация хранится в базе данных.
{{< figure src="../img/new-translation-workflow.png" title="Рабочий процесс перевода" >}}
{{% notice note %}} Если ваш модуль уже был переведен с использованием [классической системы перевода]({{< ref "classic-system" >}}), новый интерфейс перевода также может использовать переводы из существующих файлов классических словарей перевода. Это означает, что вы можете сохранить старые контроллеры для совместимости с более старыми версиями PrestaShop и добавить контроллеры Symfony для 1.7.6+, не теряя предыдущих переводов. {{% /notice %}}
Использование перевода
Чтобы сделать ваш модуль переводимым, вам нужно адаптировать его исходный код. Найдите любую фразу, которую вы хотите сделать переводимой, затем оберните ее с использованием соответствующего метода, как объяснено ниже. После обертки ваши фразы будут готовы к переводу через интерфейс перевода.
{{% notice tip %}} По умолчанию фразы отображаются в исходной версии.
Не переживайте, если вы не перевели все на все языки сразу. Любая не переведенная фраза будет отображаться на исходном языке. Поэтому мы предлагаем писать все фразы на английском языке, а затем переводить их на другие языки. {{% /notice %}}
Домен перевода {#translation-domain}
Важной частью новой системы перевода является Домен перевода, который заменяет [контекстуализацию][contextualization] классической системы. В новой системе перевода все фразы должны быть связаны как минимум с одним доменом перевода.
В то время как ядро и родные модули имеют четко определенные [схемы именования доменов перевода][core-translation-domains], ненативные модули должны соблюдать определенные правила именования:
Modules.Nameofthemodule.Specificpart
Имена доменов перевода всегда состоят из трех частей, разделенных точками:
-
Первая часть должна всегда быть "Modules"
-
"Nameofthemodule" – это имя вашего модуля, с некоторыми правилами:
- Первая буква должна быть заглавной, а остальные строчными (например, "MyModule" становится "Mymodule")
- Поддерживаются только буквенные и цифровые символы (A-z, 0-9).
Убедитесь, что техническое имя вашего модуля не содержит подчеркиваний (_) или других неподдерживаемых символов, иначе перевод может не работать. - Если имя вашего модуля начинается с
ps_, эта часть должна быть удалена. Это исключение из предыдущего правила.
-
"Specificpart" позволяет контекстуализацию и может быть установлена на ваше усмотрение, соблюдая следующие правила:
- Первая буква должна быть заглавной, а остальные строчными.
- Допускаются символы, такие как точки, дефисы и подчеркивания (но не рекомендуется).
- Если вы нацелены на версию 1.7.8 и выше, рассмотрите использование [конвенций для родных модулей][native-module-conventions] ("Admin" или "Shop").
- Если вы хотите использовать ранее созданные файлы словарей классического перевода для обратной совместимости, вам нужно следовать определенным правилам именования (объяснено ниже).
{{% callout %}}
Обратная совместимость
Если вы хотите, чтобы ваш модуль был совместим с ранее созданными [файлами словарей классического перевода]({{< ref "classic-system" >}}), то третья часть домена перевода должна быть установлена в имя файла, где используется фраза, соблюдая следующие правила:
- Первая буква должна быть заглавной, а остальные строчными
- Если расширение файла
.tpl, расширение должно быть удалено - Если имя файла заканчивается на "controller", эта часть также должна быть удалена.
Примеры
Предполагая, что ваш модуль называется "my_module":
| Файл, где используется фраза | Ожидаемый домен перевода |
|---|---|
| my_module.php | Modules.Mymodule.My_module.php |
| SomeFile.php | Modules.Mymodule.Somefile.php |
| a_certain_template.tpl | Modules.Mymodule.A_certain_template |
| ps_somefile.tpl | Modules.Mymodule.Ps_somefile |
| another-template.html.twig | Modules.Mymodule.Another-template.html.twig |
Вы можете найти больше примеров в тестовых фикстурах для DomainHelper. {{% /callout %}}
PHP файлы
В PHP файлах перевод осуществляется с помощью метода модуля trans().
Этот метод принимает четыре параметра:
$id– Фраза, которую хотите перевести.$parameters– Массив замен, если есть. (Узнать больше о заполнителях перевода).$domain– Домен перевода для этой фразы, как объяснено выше.$locale– (необязательно) Идентификатор локали (например, "en-US"), если вы хотите перевести на другой язык, отличный от текущего.
Теперь давайте посмотрим некоторые примеры использования.
Основной класс модуля
При переводе фраз в основном классе модуля, так как он расширяет класс Module, вы можете просто вызвать $this->trans().
<?php
// файл: mymodule.php
class MyModule extends Module
{
public function __construct()
{
$this->version = '1.0.0';
$this->author = 'Me';
$this->displayName = $this->trans('Мой модуль', [], 'Modules.Mymodule.Mymodule');
$this->description = $this->trans('Описание моего модуля. Сделано: %author%, Текущая версия: %version%', ['%version%' => $this->version ,'%author%' => $this->author], 'Modules.Mymodule.Mymodule');
}
}
Поскольку модуль называется MyModule, домен перевода должен быть Modules.Mymodule.Mymodule. Третья часть совпадает с именем файла, которое также является "mymodule".
Контроллеры модуля
ModuleAdminController и ModuleFrontController могут получить доступ к экземпляру модуля и переводчику через свойство $this->module и публичный аксессор getTranslator().
<?php
// файл: controllers/front/something.php
class MyModuleSomethingModuleFrontController extends ModuleFrontController
{
public function initContent()
{
$this->title = $this->module->getTranslator()->trans('Заголовок моего модуля', [], 'Modules.Mymodule.Something');
}
}
Контроллеры Symfony работают точно так же, как и контроллеры ядра. Просто используйте метод $this->trans().
{{% notice warning %}}
Имейте в виду, что в контроллерах Symfony второй и третий аргументы поменяны местами, чтобы сделать $replacements (замены) необязательным.
{{% /notice %}}
<?php
namespace PrestaShop\Module\MyModule;
class SomeAdminController extends FrameworkBundleAdminController
{
public function someAction()
{
$this->text = $this->trans('Некоторый текст, который переводится', 'Modules.Mymodule.Admin', []);
}
}
Другие классы
Другие классы должны будут каким-то образом получить экземпляр переводчика модуля. Мы рекомендуем передавать его как параметр в конструкторе и сохранять для последующего использования.
<?php
class CustomModuleClass
{
private $translator;
public function __construct(Translator $translator)
{
$this->translator = $translator
}
public function foo()
{
$this->text = $this->translator->trans('Мой текст для перевода', [], 'Modules.Mymodule.Custommoduleclass');
}
}
// из модуля:
$customModuleClass = new _NAMESPACE_\CustomModuleClass($this->getTranslator());
{{% notice info %}}
Если вам действительно нужно, вы также можете получить новый экземпляр вашего модуля, используя $module = Module::getInstanceByName('mymodulename'), а затем получить доступ к translator с помощью $module->getTranslator(). Тем не менее, этого следует избегать, так как это плохая практика.
{{% /notice %}}
Шаблоны
Файлы Twig
Фразы в файлах Twig .twig могут быть переведены с использованием фильтра trans. Он работает аналогично методу trans(), описанному выше для PHP файлов:
{# файл: something.twig #}
{{ 'Добро пожаловать на эту страницу!'|trans({}, 'Modules.Mymodule.Admin') }}
Первый параметр может быть использован для замены токенов в вашей фразе после ее перевода:
{{ 'Привет, %username%!'|trans({'%username%': 'John'}, 'Modules.Mymodule.Admin') }}
Файлы Smarty
Фразы в файлах Smarty .tpl могут быть переведены с использованием вызова функции {l}, которую Smarty заменит на перевод на текущий язык.
Эта функция принимает три параметра:
s– Фраза для перевода.d– Домен перевода.sprintf– Необязательно, может быть использован для интерполяции переменных в вашей фразе.
Например, перевод строки "Добро пожаловать на эту страницу!" можно выполнить следующим образом:
{* файл: somefile.tpl *}
{l s='Добро пожаловать на эту страницу!' d='Modules.Mymodule.Somefile'}
Вы можете заменить заполнители в ваших переводных фразах, используя параметр sprintf:
{l s='Привет, %username%!' sprintf=['%username%' => 'John'] d='Modules.Mymodule.Somefile'}
Перевод вашего модуля
Модули должны быть настроены для перевода с использованием нового интерфейса перевода в панели управления. Это можно сделать, объявив следующую функцию в основной классе модуля:
<?php
public function isUsingNewTranslationSystem()
{
return true;
}
После этого:
- Перейдите на страницу "Переводы" в меню "Международный",
- В разделе "Изменить переводы" найдите выпадающий список "Тип перевода" и выберите "Переводы установленных модулей",
- Выберите модуль, который хотите перевести.
- Выберите язык, на который хотите перевести модуль. Язык назначения должен быть уже установлен, чтобы включить перевод на него.
- Нажмите кнопку "Изменить".
Вам будет представлена страница, на которой отображаются все формулировки для выбранного модуля, сгруппированные по домену перевода.
После сохранения переводы сохраняются в базе данных в таблице ps_translations.
Появление ваших формулировок в интерфейсе перевода
Интерфейс перевода полагается на анализ кода для "обнаружения" формулировок для перевода. Поэтому, объявляя формулировки в вашем коде, необходимо соблюдать некоторые меры предосторожности, чтобы убедиться, что они могут быть обнаружены.
-
Интерфейс перевода обнаруживает только формулировки, использованные через функцию
trans(), тег Smarty{l}и фильтр Twigtrans. Поэтому они должны быть объявлены в файле PHP, TPL или TWIG. Они будут обнаружены независимо от того, используется ли этот код на самом деле в рантайме или нет. -
Всегда используйте буквальные значения, а не переменные, с функцией
trans(), тегом Smarty{l}и фильтром Twigtrans. Хотя переменные интерпретируются в рантайме, они не будут поняты анализатором кода, который поддерживает только буквальные значения. Передача переменных этим методам предотвратит появление этих формулировок в интерфейсе перевода.
Пример:
<?php
// буквальные значения будут работать
$this->trans('Некоторая формулировка', [], 'Modules.Mymodule.Something');
// динамическое содержимое может быть вставлено с использованием заполнителей и замен
$this->trans('Некоторая формулировка с %foo%', ['%foo%' => $dynamicContent], 'Modules.Mymodule.Bar');
// это не будет работать, интерпретатор проигнорирует переменные
$wording = 'Некоторая формулировка';
$domain = 'Modules.Mymodule.Foo';
$this->trans($wording, [], $domain);
// это приведет к непредсказуемым результатам
$this->trans('Некоторая '. $var . ' формулировка', [], 'Modules.Mymodule.Foo');
// динамическое поведение, такое как псевдоним функции trans(), также не будет работать хорошо
function translate($wording) {
$this->trans($wording, [], 'Modules.Mymodule.Foo');
}
В файлах Twig вы можете использовать trans_default_domain для настройки домена по умолчанию. Имейте в виду, что это работает на основе файла:
{% trans_default_domain 'Modules.Mymodule.Foo' %}
{{ 'Привет, мир'|trans }}
{{ 'Что-то еще'|trans }}
Распространение ваших переводов
Экспорт переводов
{{< minver v="1.7.8" title="true" >}}
Начиная с PrestaShop 1.7.8, вы можете экспортировать все переводы модуля в файлы XLF, которые можно распространять вместе с вашим модулем.
Чтобы экспортировать файлы перевода:
-
Перейдите на страницу "Переводы" в меню "Международный",
-
В разделе "Экспорт переводов":
- Выберите язык,
- Выберите "Переводы установленных модулей", затем модуль, который хотите экспортировать,
- Нажмите на "Экспорт"
Вы можете распространять загруженные словари, поместив извлеченные файлы в папку translations вашего модуля, вот так:
.
└── mymodule/
└── translations/
├── fr-FR/
│ ├── ModulesMymoduleFoo.fr-FR.xlf
│ └── ModulesMymoduleBar.fr-FR.xlf
└── en-US/
├── ModulesMymoduleFoo.en-US.xlf
└── ModulesMymoduleBar.en-US.xlf
{{% notice warning %}} Обратите внимание, что эти файлы будут работать только с PrestaShop 1.7.8 и выше. Если вам нужно обеспечить совместимость с предыдущими версиями, читайте ниже. {{% /notice %}}
Рекомендуемая практика создания переводов модуля
Для разработчиков модулей, если вы хотите включить ваши окончательные переводы в модуль без создания файла xlf вручную, рекомендуемая практика такова:
- Подготовьте ваши переводы (см. "[Появление ваших формулировок в интерфейсе перевода]({{<relref "#making-your-wordings-appear-in-the-translation-interface">}})").
- Переведите их вручную в панели управления.
- Экспортируйте переводы (см. "[Экспорт переводов]({{<relref "#exporting-translations">}})") и добавьте их в папку переводов вашего модуля.
Эти переводы будут настроены в PrestaShop во время установки модуля.
До 1.7.8
Если вам нужно распространять обратно совместимые переводы, вы можете либо [написать классические словари вручную]({{< ref "classic-system#editing-a-dictionary-file-manually" >}}), либо экспортировать формулировки вашего модуля из базы данных в файл, а затем импортировать его во время установки модуля.
Если вы решите экспортировать формулировки из базы данных, вы можете легко извлечь формулировки вашего модуля из таблицы ps_translation, отфильтровав домены, начинающиеся с ModulesYourmodulename*. При вставке переводов в целевой магазин не забудьте установить соответствующее значение для id_lang в соответствии с конфигурацией языка целевого магазина (см. таблицу ps_lang).
[контекстуализация]: {{< ref "new-system.md#contextualization" >}} [конвенции-нативных-модулей]: {{< ref "/8/development/internationalization/translation/translation-domains.md#modules" >}} [домены-перевода-ядра]: {{< ref "/8/development/internationalization/translation/translation-domains.md#understanding-the-domains-structure" >}}
