Возможности перевода в Zend Framework 2 с применением I18n

languages

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

Возможности и реализация перевода в Zend Framework 2

 

В ZF2 перевод реализует класс (полный путь Zend\I18n\Translator\Translator). Этот гибкий инструмент имеет несколько способов конфигурирования.
Самый простой это метод addTranslationFile() содержит следующий набор параметров:

  • $type – это тип файла содержащего перевод из перечисленных ниже.
  • $filename – полный путь к файлу. альтернативный вариант это задать паттерн, о нем дальше.
  • $textDomain – контекст. по умолчанию ‘default’
  • $locale – локаль языка в виде ru_RU, en_US

Пример использования:

Так же вместо указания одного файла можно задать паттерн, который будет искать все файлы с заданным расширением по заданному пути. Например:

Пример паттерна – /var/messages/%s/messages.mo

Список поддерживаемых форматов перевода:

Содержание файла PHP очевидно будет иметь вид ключ-значение, где ключем будет переводимая строка, а в значении – перевод. Это самый простой формат. Например перевод на немецкий:

Содержимое INI файла будет выглядеть как набор строк message и translation. Так же перед каждым переводом можно указать группу (это и есть тот самый контекст из параметров выше).

Формат INI уже больше похож на Gettext по своей структуре, но все таки он слишком спецализирован и уступает Gettext по возможностям и популярности. Например, популярная CMS WordPress переводится с помощью Gettext. Рассмотрим Gettext формат:

Тут видно, что в комментарии можно указать произвольный текст, например путь к файлу. Далее идет переводимая строка msgid и перевод msgstr. Преимущество Gettext в том, что PO файлы компилируются в MO файлы, которые сжаты и легче читаются программой. Но с Gettext сложнее работать, если переводы можно редактировать просто в редакторе, то все равно нужен компилятор MO.

Я не рассматриваю перевод для множественного числа, скажу лишь, что для этого есть translatePlural() и так же существуют правила для каждого языка, как единственное число преобразуется в множественное, выраженные в формулах. Эти формулы очень полезны для PO редакторов, найти их можно тут – http://docs.translatehouse.org/projects/localization-guide/en/latest/l10n/pluralforms.html

Для настройки использования Gettext в Zend нужно добавить следующий конфиг в модуль:

Тут указывается настройки сервиса, а именно локаль по умолчанию, тип файлов перевода и шаблон пути к файлам. Параметры cache не обязательные, но лучше их указывать для производительности.

По умолчанию вместе с Zend Skeleton  идет модуль Application в котором можно увидеть множество PO и MO файлов. Взяв за основу предлагаемый ru_RU.po файл, я решил расширить его нужными мне переводами. Для этого я поискал инструмент для редактирвоания, т.к. редактировать в IDE мне не понравилось. Самый популярный редактор для PO это PoEdit и он мне не понравился. Может быть он хорош для перевода PO, но я так и не нашел в нем возможность добавлять новые не вереведенные фразы. Я исследовал еще несколько редакторов, включая GTranslator, Babel, Virtaal и poeditor и ни один из них не показался мне достаточно удобным и завершенным.
В итоге я решил использовать онлайн сервис, в котором можно добавлять фразы, переводить, сохрнанять и компилировать MO – https://localise.biz/free/poeditor

Более подробная информация по Translator в документации – http://framework.zend.com/manual/current/en/modules/zend.i18n.translating.html

 

Практическое применение

 

Для начала несколько примеров использования Translator в разных местах фреймворка. Эти примеры будут корректными при условии, что в конфигурации route текущего запроса есть параметр locale.

В конфигурации:

В модуле

В экшине контроллера:

Но самое интересное и удобное, что есть у Zend Framework 2 по переводам это View хелперы:

  • Currency Format Helper
  • Date Format Helper
  • Number Format Helper
  • Plural Helper
  • Translate Helper
  • Translate Plural Helper

Многие из этих хелперов (если не все) используют php расширение intl.
Из них самые часто используемые должны быть Date и Translate, их я и использовал. Учитывая сконфигурированный путь к MO файлам, Translator подхватывает переводы автоматически.
Например этот код

выдаст мне анкор “Политика конфиденциальности”, т.к. я добавил перевод в ru_RU.po и добавил скомпилированный ru_RU.mo

Если с Translator все просто, то вот с Date Formatter есть нюансы. Он сделан не очень гибко и поддерживает форматирвоание только с использованием преодпределенных констант расширения intl.
Например

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

Я привожу так же метод с форматированием \DateTime, чтобы была разница. Используется мой ViewHelper так

Получаю 19 Марта вместо 19 March. Список доступных форматов дат, которые использует intl – http://userguide.icu-project.org/formatparse/datetime

Документация по остальным View Helper – http://framework.zend.com/manual/current/en/modules/zend.i18n.view.helpers.html

Так же в Zend 2 на основе intl сделаны мощные фильтры и валидаторы, информацию о которых можно найти по ссылке выше.

В завершение хочу порекомендовать отличный модуль, который автоматичеки встраивает Twitter Bootstrap в рендеринг ZF2 форм. Просто создав класс MyForm и вызвав его рендеринг можно сразу же получить форму в разметке Bootstrap, а для более гибкой верстки у модуля существует множество методов. Я упоминаю этот модуль тут, т.к он автоматически переводит Label к полям формы (при наличии перевода в файле перевода и конфигурации) и так же Value в кнопках и другое.

Модуль Zf2-twb-bundle