Локализация приложений с помощью gettext

Проблема локализации (интернационализации) программ и сайтов

Ни для кого не секрет, что использование латинского алфавита, а точнее – английского языка, де-факто является стандартом при разработке приложений. Установился ли такой уклад спонтанно или был обусловлен действием сторонних факторов – точно утверждать нельзя, но факт остаётся фактом: практически всегда при создании документации к ПО и элементов взаимодействия с пользователем (интерфейса) используется именно английский язык.
В то же время, наличие локализации и, что ещё важнее – качественной локализации, играет важнейшую роль при коммерческом использовании и/или популяризации ПО.



Самый очевидный способ локализации программного продукта – это внесение соответствующих изменений непосредственно в исходный код, т.е. поиск и перевод отдельных элементов (сообщений, названий, подписей и т.п.), которые используются при визуальном отображении.

Насколько такой подход неэффективен, говорить не имеет смысла: дополнительные затраты времени, ресурсов, возникновение проблем технического характера (например, несоответствие кодировок символов), кроме того, с выходом новой версии ПО перевод придётся делать заново.

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

Локализация приложений с помощью GetText


Идея системы GetText возникла в рамках проекта GNU для интернационализации (GNU Translation Project), когда разработчики GNU столкнулись с проблемой локализации своих программ. Основой системы является библиотека gettext, которая поддерживается большинством языков программирования: C++, Objective-C, C#, сценарии sh и bash, Python, Perl, PHP, Java, GNU awk, Pascal (Free Pascal Compiler), YCP (язык YaST2), Tcl, Pike (поддержка языков программирования).

Данная библиотека обеспечивает вызов специальной функции gettext (для простых строк) или ngettext (для множественного числа), с помощью которой в исходном коде размечаются строки, подлежащие переводу. Обычно для уменьшения размера исходников и улучшения читаемости кода, для gettext объявляют и используют короткий синоним _ (символ подчёркивания) или __ (двойной символ подчёркивания), реже – символы _c или _e.
Таким образом, вызов

printf ("Hello! My name is %s.\n", my_name);


преобразуется в

printf (_("Hello! My name is %s.\n"), my_name);

На практике, разработчики часто вместе с общепринятыми обозначениями используют ряд своих. Например, в современных версиях Wordpress встречаются конструкции:

 __ngettext:1,2, _n:1,2, _nc:1,2 или даже__ngettext_noop:1,2.

Комментарии обычно размещают непосредственно перед строками, которые необходимо перевести (в данном случае комментарий обозначается символами ///):

/// ПЕРЕВОДЧИКАМ: пожалуйста, оставьте конструкцию '%s.\n' без изменений, т.к. это необходимо для корректной работы программы.

printf(_("My name is %s.\n"), my_name);

Также, разработчику необходимо установить в программе параметры локализации, к которым относятся: текущий язык и кодировка (локаль); путь к директории с файлами локализации; название файла с переводом (т.н. домен). Для этого, необходимо ориентироваться в двухбуквенных сочетаниях обозначения языков, языковых тэги и кодах, которые можно узнать из специальной таблицы или из документации по GetText.

Кроме библиотек в систему GetText входит набор специальных утилит для работы с размеченными в исходном коде строками. Обратите особое внимание: если вы работаете в ОС Unix (Linux), то дополнительной настройки GetText не требуется – все нужные утилиты и библиотеки уже интегрированы. Для Windows-систем необходимо установить скомпилированные под Win32 файлы библиотеки gettext, файлы iconv (библиотека для преобразования текста из одной кодировки в другую) и вспомогательные утилиты (всё указанные файлы можно взять здесь).

 С помощью одной из таких утилит – xgettext – размеченные строки извлекаются из кода (скрипта). Для дополнительного функционала при вызове утилиты xgettext используются определённые параметры (об опциях xgettext можно почитать тут) – в данном примере дополнительно извлекаются комментарии отмеченные символами

xgettext --add-comments=///

Результатом работы утилиты, согласно примеру, станет файл шаблона с расширением .pot следующего содержания:

#. ПЕРЕВОДЧИКАМ: пожалуйста, оставьте конструкцию '%s.\n' без изменений, это необходимо для корректной работы программы.

#: src/name.c:36
msgid "My name is %s.\n"
msgstr ""

Теперь, на основе имеющегося файла шаблона с помощью утилиты msgіnіt необходимо создать .po-файл, указав язык, на который будет осуществляться перевод:

msginit --locale=ru --input=name.pot

В результате получаем файл с расширением .po следующего содержания:

#: src/name.c:36
msgid "Hello! My name is %s.\n"
msgstr ""

Теперь .po-файл готов для передачи переводчикам, задачей которых станет заполнение пустых строк (в кавычках). После окончания перевода необходимо скомпилировать .po-файл, чтобы информация из него стала доступной для интерпретации программой – это обусловлено тем, что в силу особенностей технологии, программа не может работать непосредственно с .po-файлом. Компиляция осуществляется утилитой msgfmt, в результате работы которой появляется бинарный файл с расширением .mo. Важное замечание: редактировать .mo-файл нельзя, а все изменения вносятся в него через соответствующий .po-файл, с последующей его компиляцией.

Практическое использование gettext для перевода строковых ресурсов – редактор poEdit


Возможно, всё сказанное выше кажется достаточно сложным и запутанным. Это не удивительно, потому что до этого момента рассматривались теоретические основы, необходимые для понимания технологии в целом. Далее мы рассмотрим практические приёмы локализации, основанные на применении системы GetText.

Для этой цели воспользуемся бесплатным кросс-платформенным (достоверно проверено в среде Unix/Linux и Windows) редактором каталогов локализации для gettext – программой poEdit (скачать poEdit можно на официальном сайте). Пользователи Unix-систем также могут воспользоваться редакторами KBabel (KDE) или GTranslator (GNOME) – программами, которые по своим возможностям и принципам работы практически идентичны poEdit.

При первом запуске необходимо будет выбрать язык интерфейса – poEdit поддерживает большое количество языков интерфейса, в том числе и русский. Также редактор попросит ввести ваше имя и e-mail; остальные настройки оставляем без изменений, тем более, что их (включая язык интерфейса и личные данные) можно будет в дальнейшем изменить. Небольшое замечание: если в процессе работы вы планируете иметь дело только с одним видом исходных файлов (например, только *.php), то в Установках на вкладке Парсеры желательно оставить только нужный парсер исходного кода, а остальные удалить.

Запускаем программу и через меню Файл создаём новый каталог; в появившемся окне поочередно заполняем все три вкладки. На вкладке Пути задаём путь (пути), где находятся файлы проекта. В нашем случае, указаны точка и две точки – это означает, что файлы проекта и файлы локализации будут находиться в одной директории. На вкладке Ключевые слова задаём символы, указывающие строки, требующие перевода – какие именно это символы, известно из теории. В открывшемся окне выбираем ту же папку, где располагаются файлы проекта, и сохраняем .ро-файл согласно домену, который задал разработчик: обычно, для русской локализации это ru_RU.po или название_проекта-ru_RU.po.

Это и будет файл, содержащий в себе все сообщения, которые нуждаются в переводе. После сохранения появится окно Сводка об обновлении с перечнем всех текстовых строк, которые будут записаны в файл; во второй вкладке будут показаны те строки, которые удалены за ненадобностью из исходников. После нажатия «ОК», .po-файл будет обновлен. Заметьте: по умолчанию бинарный .mo-файл будет компилироваться автоматически при сохранении .po-файла (если данная опция не отключена в настройках). Основное окно редактора разделено на три части.

В первой – все сообщения, которые содержатся в файле (файлах), причём непереведённые и закомментированные сообщения всегда подсвечиваются и помещаются в начало списка. Во второй части окна содержится сообщение, которое переводится в данный момент (оригинальный текст), а в третьей части – перевод. Кстати, редактор поддерживает практически все языки, даже такие экзотические для нас, как китайский и арабский. Опционально, есть возможность вызвать окно редактирования комментариев, где можно дать пояснения к любой строке.

Если по каким-то причинам смысл текста не понятен и/или необходимо посмотреть исходный код, то это можно сделать во встроенном вьюере – правый клик мыши на строке, пункт Связи. Об одной из функций poEdit – автоматическом переводе – имеет смысл сказать отдельно. Суть функции заключается в том, что программа пытается автоматически переводить строки, если они близки к имеющимся записям в базе данных, содержащей набор ранее переведенных текстов, т.е., другими словами, мы имеем дело с памятью переводов (ПП).

Само собой, без такой базы данных функция автоматического перевода особой пользы не представляет, поэтому у пользователя есть возможность, кроме подключения уже имеющейся БД, создать собственную. Последний вариант выглядит особенно предпочтительно для людей, которые работают с шаблонными (однотипными) переводами или стандартизированными терминами – у них есть возможность создать базу «под себя» и экономить время, избавившись от рутинного перевода повторяющихся строк.

Если же использовать стороннюю БД или БД ориентированную на другую тематику, то применение автоматического перевода может и не дать ожидаемого результата – переведенные строки придётся корректировать и уточнять. В любом случае, строки, переведённые автоматически, poEdit помечает как «нечёткие» или «неточные» (от англ. «fuzzy»), т.е. требующие проверки. «Узким местом» реализации памяти переводов в poEdit является отсутствие поддержки наиболее распространенных форматов ПП, в том числе и международного стандарта TMX (Translation Memory Exchange Format).

Для генерации памяти переводов poEdit использует .ро и .mo-файлы, которые «заливаются» в базу, после чего их содержание становится доступным при автоматическом переводе. В настройках poEdit на вкладке Память переводов в строке «Пути к БД» необходимо указать рабочую папку перевода (обычно, директория программы), т.е. папку, где будет храниться созданная БД, и добавить язык, с которым вы собираетесь работать (если перевод будет осуществляться на русский язык, добавляем ru).

Далее, генерируем базу данных, указав .po-файл как источник. После выполненных действий poEdit будет откликаться на выбор Перевести автоматически, используя ПП из меню Каталог, а также задействует автоматический перевод при обновлении каталога (если данная опция не отключена в настройках ПП). После того, как файлы локализации готовы, их оставляют в корневой директории проекта или перемещают в отдельную «языковую» папку с названием lang или languages, в зависимости от того, как предусмотрел разработчик.
Несмотря на то, что для корректной работы локализации необходимы только .mo-файлы, .po-файлы обычно также оставляют, на случай, если в дальнейшем понадобится внести изменения в перевод.

Преимущества и недостатки инструмента локализации (интернационализации) приложений gettext


Не нужно думать, что система GetText является единственной технологией в своём роде. Другое дело, что наряду с другими подобными инструментами она имеет некоторые конкурентные преимущества. Основным отличием GetText от системы, например, catgets или технологии использования функции LoadString в среде MS Windows, является использование оригинальных строк (строк на английском языке) вместо специальных идентификаторов (обычно – числовых) в коде программы, а также поддержка множественного числа.
Кроме этого, в GetText есть ещё одна очень важная особенность: если какие-то строки не были по каким-то причинам переведены, то GetText вернет их на языке по умолчанию (обычно – английский), что очень удобно, так как не приводит к появлению ошибок. В то же время, при использовании GetText существует ряд трудностей на этапе подготовки программного продукта к локализации.

Причём, все эти трудности полностью ложатся на плечи разработчика, который должен позаботиться о возможности локализации своей программы (скрипта) внеся в исходный код соответствующую разметку, выделяя требующие перевода строки. Естественно, что это требует дополнительных затрат времени, но если локализация средствами GetText не будет заложена изначально, то перевести продукт на другой язык можно будет только через внесение изменений непосредственно в исходный код.

 Несмотря на это, заслуга создателей технологии GetText состоит в том, что они предложили относительно несложный, достаточно функциональный и, что самое главное, унифицированный инструмент для локализации приложений. Возможно, именно поэтому система GetText на сегодняшний день является одной из самых популярных в сегменте веб-программирования, например, при локализации (часто – силами энтузиастов) бесплатных open-source проектов – шаблонов и «движков» для сайтов, блогов, Интернет-магазинов и т.п., а также дополнений к ним (плагинов, визуальных тем).

 Если же говорить о главном инструменте для создания файлов локализации в среде ОС Windows – программе poEdit, то работа с ней не сложнее, по своей сути, работы с обычным текстовым редактором. Наибольшим же недостатком poEdit является, кончено, отсутствие полноценной поддержки памяти переводов.

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

1 комментарий:

  1. Добрый день! Если Вы заинтересованы в локализации web-ПО, ПО для персональных компьютеров, ПО для мобильных устройств либо иного вида программного обеспечения, я рекомендую Вам использовать этот инструмент на базе web: http://poeditor.com/ POEditor является интуитивным, хорошо проработанным инструментом, обладающим рядом полезных свойств, которые помогают организовать процесс управления переводом. Он поддерживает множество популярных форматов файлов и обладает собственным API, что обеспечивает лучшую автоматизацию. Желаю Вам больших успехов в Ваших проектах!

    ОтветитьУдалить