Статьи

Локализация PHP-приложений «Правильный путь», часть 5

В четвертой части вы узнали, как использовать gettext для одного из самых сложных аспектов локализации, с которым может столкнуться разработчик — множественного числа. В этой заключительной части серии из пяти частей я научу вас, как автоматизировать часть процесса локализации, извлекая msgids и создавая файл шаблона PO ( .pot ) из кода PHP вашего приложения. Давайте погрузимся прямо в!

Извлечение строк из источника

Вы видели, насколько мощным является gettext, и как легко было включить локализацию в ваши приложения. Но как насчет текущего обслуживания? По мере развития вашего приложения текстовые строки обязательно будут добавляться, обновляться и удаляться. Извлечение строк для использования в качестве msgids и организация их вручную — сложная задача, даже с небольшой базой кода. Вот где может помочь xgettext.

xgettext — это инструмент командной строки, который является частью библиотеки gettext, которую вы скачали и установили в части 1 … действительно очень полезный инструмент! Его цель — упростить извлечение строк из исходного кода и создать шаблон домена, тем самым экономя ваше время и нервы. xgettext не является специфичным для PHP; Вы можете использовать его для извлечения строк из кода, написанного на более чем 15 популярных языках программирования, включая C, C ++, C #, Java, Perl, PHP и Python и многие другие.

Прежде чем начать, убедитесь, что ваш каталог Test18N обновлен со следующей структурой, созданной в предыдущих частях этой серии.

another directory recap

Откройте test_locale.php и замените его содержимое следующим кодом:

 <?php require_once "locale.php"; echo _("Hello World!") . "<br>"; echo _("Testing Translation...") . "<br>"; echo _("Please login first:") . "<br>"; echo _("Click on the link below") . "<br>"; echo _("Shutdown system") . "<br>"; echo '<a href="test_page_1.php">' . _("Go To Page 1") . "</a>"; 

Затем создайте новый файл с именем test_page_1.php со следующим содержимым:

 <?php require_once "locale.php"; echo _("Errors occurred") . "<br>"; echo _("Please fix this") . "<br>"; echo _("Click on the link below") . "<br>"; echo dgettext("errors", "Error getting content") . "<br>"; echo dgettext("errors", "Error saving data") . "<br>"; echo '<a href="test_locale.php">' . _("Back To Home") . '</a>&nbsp;|&nbsp;<a href="test_page_2.php">' . _("Go To Page 2") . "</a>"; 

И наконец, создайте новый файл с именем test_page_2.php со следующим содержимым:

 <?php require_once "locale.php"; echo _("If you want to read more") . "<br>"; echo _("Please login first:") . "<br>"; echo sprintf(ngettext("%d file", "%d files", 1), 1) . "<br>"; echo sprintf(ngettext("%d file", "%d files", 2), 2) . "<br>"; echo sprintf(ngettext("%d file", "%d files", 5), 5) . "<br>"; echo '<a href="test_locale.php">' . _("Back To Home") . '</a>&nbsp;|&nbsp;<a href="test_page_1.php">' . _("Go To Page 1") . "</a>"; 

Теперь у вас должно быть три файла для эмуляции приложения чуть большего размера. И, как в реальном приложении, вы заметите, что некоторые сообщения повторяются в более чем одном файле. Если бы вы извлекали строки вручную, вам пришлось бы сортировать их и удалять любые дубликаты при создании файла перевода.

Теперь о магии автоматизации. Откройте окно терминала, перейдите в каталог Test18N и выполните следующую команду:

  abouzekry @ sandbox: ~ / htdocs / Test18N $ xgettext --from-code = UTF-8 -o messages.pot * .php 

Это указывает xgettext на извлечение сообщений из всех файлов PHP в текущем каталоге. xgettext предполагает, что любой файл является ASCII по умолчанию, и его вывод может содержать неожиданные результаты, если исходные строки содержат любые не-ASCII символы. Чтобы быть в безопасности, я переопределил его предположение с UTF-8, используя опцию --from-code . Опция -o указывает xgettext записать свои выходные данные в файл с именем messages.pot , базовый файл, который вы вскоре будете использовать для всех ваших переводов.

Прежде чем идти дальше, стоит отметить, что xgettext имеет некоторые ограничения. Наиболее заметно он записывает все строки в один файл (например, dgettext() использует dgettext() для поиска некоторых переводов в области ошибок, но все строки были помещены в messages.pot ). Вы можете использовать только один домен или впоследствии разделить messages.pot на соответствующие файлы. Мне действительно нравится иметь специализированные переводческие домены, чтобы все было организовано, поэтому я буду поощрять этот подход.

Скопируйте файл messages.pot качестве errors.pot и отредактируйте errors.pot чтобы удалить все сообщения, кроме тех, которые относятся к домену ошибок. Вы должны хранить только следующие сообщения:

  #: test_page_1.php: 9
 msgstr "Ошибка при получении контента"
 msgstr ""

 #: test_page_1.php: 10
 msgstr "Ошибка сохранения данных"
 msgstr "" 

Затем отредактируйте messages.pot чтобы удалить messages.pot об ошибках из этого файла.

Использование шаблонов

Теперь у вас есть два шаблона, один для домена messages.pot ( messages.pot ) и другой для домена ошибок ( domain.pot ). Запустите Poedit, выберите « File > « New catalog from POT file и откройте messages.pot .

poedit menu

Заполните необходимые параметры, как описано ранее в части 2 . Я буду создавать каталог на французском языке с использованием кодировки UTF-8. Также важно указать соответствующее выражение множественного числа. Для французского это «nplurals = 2; множественное число = п> 1;». После того, как вы нажмете ОК, вам будет предложено сохранить новый PO-файл, созданный из шаблона. Сохраните его как соответствующий Locale/fr_FR/LC_MESSAGES/messages.po .

poedit settings window

Затем Poedit открывает PO-файл и отображает исходные строки и их переводы. Вы можете добавить свои переводы непосредственно в Poedit или отправить файл своему переводчику для работы, пока вы сосредоточены на PHP-коде своего приложения.

Как примечание, работать с множественными формами в интерфейсе Poedit легко. Когда вы щелкнете по форме единственного числа в списке переводов, вы увидите вкладки внизу для каждой формы, в которые вы можете ввести соответствующие переводы.

poedit

Как только вы закончите предоставлять переводы для каждого сообщения, выберите « File > « Save или щелкните запись « Save Catalog на панели значков, чтобы сохранить и создать необходимый файл MO. Затем выполните ту же процедуру для errors.pot , сохранив ее в Locale/fr_FR/LC_MESSAGES/errors.po . Вам нужно будет повторить процесс для каждого шаблона для каждого имеющегося у вас языка.

Когда, по крайней мере, есть MO-файлы французской локали, протестируйте скрипт test-locale.php чтобы убедиться, что все работает.

Резюме

В этой последней части серии вы узнали, как автоматически извлекать строки перевода из исходных файлов PHP с помощью инструмента xgettext, генерируя файл шаблона PO. Затем шаблон можно использовать для создания любых каталогов целевых доменов, которые вам нужны, тем самым оставляя громоздкий процесс извлечения сообщений на компьютер.

В пяти частях вы узнали, что локализация может быть просто вопросом написания отдельных файлов перевода для целевой локали, а затем на нее ссылаются, используя gettext() , его сокращенный псевдоним _() и его множественное число, аналог ngettext() . Вы также видели, как использование альтернативного поведения gettext может привести к более удобочитаемому коду и каталогам переводов, и как переводы могут быть аккуратно организованы в свои собственные домены ( messages.po для общих сообщений, errors.po для строк ошибок и т. Д. ).

Я с удовольствием писал эту серию и хочу поблагодарить вас за то, что вы нашли время, чтобы научиться правильно «локализовывать» ваши PHP-приложения с помощью gettext. gettext действительно замечательный инструмент с открытым исходным кодом, который помогает сделать вашу жизнь проще, позволяя вам сосредоточиться на своем коде.

Изображение через sgame / Shutterstock