Интернационализация(локализация) для разработчиков WordPress.

УрокиКомментариев нет

Документация по интернационализации плагинов располагается теперь в Пособии по разработке плагинов

Документация по локализации плагинов располагается теперь в Пособии по разработке плагинов

Документация по интернационализации тем располагается теперь в Пособии по разработке тем

Документация по локализации тем располагается теперь в Пособии по разработке тем.

Что такое интернационализация

Интернационализация — это процесс разработки плагина, с учетом того, что он может быть с легкостью переведен на другие языки. Локализация описывает последующий за этим процесс перевода плагина, разработанного таким образом. Интернационализация в английском языке часто обозначается аббревиатурой «i18n» (в слове «internationalization» между первой и последней буквой располагается как раз 18 символов), а локализация — аббревиатурой «l10n» (в слове «localization» между первой и последней буквой имеется 10 символов).

Почему интернационализация так важна?

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

Введение в Gettext

Для интернационализации в WordPress используются библиотеки и инструменты gettext. Gettext — это давнее и довольно хорошо зарекомендовавшее себя ПО, используемое в мире программ с открытым кодом.

Вот, в двух словах, как оно работает:

  • Разработчики «оборачивают» строки, которые требуют перевода, в специальные функции gettext.
  • Специальные инструменты анализируют файлы исходного кода и извлекают строки для перевода в POT-файлы (Portable Objects Template — Шаблон портируемых объектов)
  • В WordPress POT-файлы чаще всего «скармливаются» GlotPress, который является инструментом совместной работы для переводчиков.
  • Переводчики делают свое дело и в результате получается PO-файл (POT-файл, но с переводом внутри)
  • PO-файлы компилируются в бинарные MO-файлы, которые обеспечивают быстрый доступ к строкам уже во время работы системы.

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

Заметьте, что в уже работающей системе вы увидите функцию _(), которая ссылается на оригинальную php-функцию, совместимую с gettext, но в WordPress вы должны пользоваться функцией WordPress — __().

Текстовые домены

Если вы переводите плагин или тему, вы должны использовать текстовый домен для обозначения всего текста, который принадлежит данному плагину. Это улучшает возможности по портированию и переводу, а также увеличивает совместимость с уже существующим инструментарием WordPress. Текстовый домен должен соответствовать «слагу» данного плагина.

Текстовый домен надо добавить в заголовок плагина. WordPress должен интернационализировать метаданные вашего плагина или темы при отображении плагина в админ-панели:

Текстовый домен — это уникальный идентификатор, который позволяет WordPress различать все загруженные переводы. Если ваш плагин — единственный файл с названием my-plugin.php или он содержится в папке my-plugin, имя домена должно быть my-plugin. Имя текстового домена может содержать тире, но не должно содержать подчеркиваний.

В более глобальном плане, приложение может использовать более одного логического переводимого модуля и, соответственно, другой MO-файл. Текстовый домен — это ссылка на каждый такой модуль, имеющий отличный MO-файл.

Строки для перевода

Переводимые строки

Для того, чтобы сделать строку в вашем приложении переводимой, вы должны «обернуть» ее в вызов функции __():

Если ваш код предполагает вывод строки в браузер, тогда используйте функцию _e:

Строки для перевода «обертываются» в набор специальных функций. Наиболее часто используемой является __(). Она просто возвращает перевод своего аргумента на другой язык :

Другим простым примером является _e(), которая выводит (echo) переводимую строку вместо того, чтобы ее просто вставить:

Заполнители

Как бы вы интернационализировали эту строку. Давайте попробуем вместе:

Но это не будет работать! Помните, строки для перевода извлекаются из исходников, поэтому переводчики увидят, что надо перевести фразу «We deleted $count spam messages.» (мы удалили $количество спам-сообщений — прим. перев.) . Однако, в приложении _e будет вызвано с аргументом, таким, например, как этот: «We deleted 49494 spam messages.», gettext не найдет подходящего перевода для этого и вернет ее, как есть, без перевода. Таким образом, перевода не получится.

Решением является использование функций из серии printf. В особенности полезными являются printf и sprintf. Вот правильное решение для перевода строки о спаме:

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

Если у вас более одного заполнителя в строке, рекомендуется использовать перестановку аргументов. В этом случае одинарные кавычки обязательны: двойные кавычки заставят php интерпретировать $s, как переменную, чего нам не нужно.

Здесь ZIP-код отображается после города. В некоторых языках желательно отображать их в обратной последовательности. Использование префикса %s в примере выше решает эту проблему. Перевод, таким образом, будет написан так:

HTML

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

Пример ссылки (отделенной от окружающего ее текста):

Пример ссылки в параграфе (не отделенной от окружающего ее текста) с использованием wp_kses() для того, чтобы убедиться в правильном выводе результирующей строки:

Множественное число

Давайте вернемся к примеру о спаме. Что если мы удалили всего одно письмо-спам? Результат будет таким: «We deleted 1 spam messages» (примерно можно перевести, как «мы удалили 1 спам-сообщения» — прим. перев.), что, с точки зрения правил английского языка, неверно и, наверняка, будет неверно также и для других языков.

В WordPress можно использовать функцию _n() :

_n() получает 4 аргумента:

  • Строку в единственном числе.
  • Строку во множественном числе
  • Количество, на основании которого решается, которую форму строки использовать (хотя, есть языки с более, чем двумя формами выражений единственности или множественности).

Текстовый домен — четвертый опциональный параметр. Результат — переведенная строка в соответствии с обозначенным количеством.

Учтите, что некоторые языки используют форму единственного числа для таких количеств, как 21, 31 и так далее, примерно, как 21st, 31st в английском языке. Если хотите указать этот специальный случай, надо производить такую проверку:

Также учтите, что параметр $count часто используется дважды. Первый передается в _n() для определения, какую строку использовать, а второй — в функцию printf() для замены количества в переводимой строке.

Устранение противоречий в контексте

Иногда определенный термин используется в различных контекстах. Хотя это и одно и тоже слово на английском, в некоторых языках может потребоваться разный его перевод. Например, слово «Post» может быть использовано, и как глагол («Click here to post your comment» — «Нажмите здесь для того, чтобы написать комментарий»), и как существительное («Edit this post» — «Редактировать это сообщение»). В таких случаях используется функция _x() . Она похожа на __(), но имеет дополнительный аргумент — контекст:

Используя этот метод, мы увидим строки «Comment» в обоих случаях, но переводчики увидят две строки «Comment», каждая в своем отличном контексте.

Текстовый домен — третий опциональный параметр:

Учтите, что аналогично __(), _x() имеет также echo-версию: _ex(). Предыдущий пример можно написать вот так:

Используйте тот вариант, который улучшает удобочитаемость кода и упрощает его написание.

Для добавления контекста к строкам с формами множественного числа используйте _nx(). Если перевод требует экранирования, используйте esc_attr_x() или esc_html_x().

Описания

Как вы думаете, переводчики знают, как перевести вот это:

Вряд ли… В таких случаях можно добавить разъясняющий комментарий в исходный код. Он должен начинаться со слов translators: и должен быть последним комментарием php перед вызовом gettext. Вот пример:

Добавление translators: позволяет написать «персональное» сообщение переводчикам, чтобы они знали, как поступать с этой строкой.

Символы новой строки

Gettext не любит \r (ASCII-код: 13) в строках для перевода, так что, пожалуйста, используйте вместо этого \n.

Пустые строки

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

Если все же перевод пустой строки в вашем случае оправдан, добавьте контекст (см главу «Устранение противоречий в контексте» выше — прим. перев.) для помощи переводчикам и для устранения конфликта с Gettext.

Управление файлами JavaScript

Для добавления переводимых строк и других данных в предварительно записанный скрипт используйте wp_localize_script().

В самом же файле JavaScript, который соответствует метке script-handle, вы можете использовать переменную objectL10n.:

Интернационализация для виджетов

WordPress 2.8+ использует новый Widget API, который требует от разработчика лишь расширить функциональность стандартного класса виджета и некоторых его функций. В этом API нет функции init. После того, как виджет написан с использованием методов widget(), form(), и update(), виджет должен быть зарегистрирован. После регистрации виджета загружается текстовый домен.

Пример:

Этот пример регистрирует виджет под именем Foo_Widget, затем устанавливает значение переменной каталога плагина и пытается загрузить файл foo_widget-locale.po.

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

Пока мы не изучили некоторые примеры, специфические для WordPress, потратьте время на изучение короткой, но замечательной статьи в руководстве по gettext. В общем, статья говорит о следующих рекомендациях:

  • Классический английский язык — минимизируйте использования сленга и аббревиатур
  • Полные предложения — в большинстве языков порядок слов отличается от такового в английском языке
  • Разделение по параграфам — объединяйте связанные предложения, но не пытайтесь перевести целую страницу в одной строчке
  • Использование форматирования строки вместо слияния строк — всегда лучше использовать sprintf(__(‘Replace %1$s with %2$s’), $a, $b); вместо __(‘Replace ‘).$a.__(‘ with ‘).$b;
  • Избегайте использования необычной разметки и необычных управляющих символов — не включайте тэги, которые окружают ваш текст и не вставляйте в строку ссылки, если только они не имеют своей версии на языке перевода
  • Не оставляйте пробелов в начале и в конце строки для перевода

Загрузка текстового домена

Имя текстового домена также используется для формирования имени MO-файла перевода вашего плагина. Вы можете загрузить их, вызвав функцию load_plugin_textdomain, на этапе выполнения действия plugins_loaded.

Пример:

Этот вызов пытается загрузить my-plugin-{locale}.mo из вашего базового каталога плагинов. locale — это код языка и/или код страны, который вы определили в константе WPLANG в файле wp-config.php. Например, код для немецкого языка — ‘de’, а для датского — ‘da_DK’. Из примера выше текстовый домен — ‘my-plugin’, поэтому датские файлы MO и PO должны быть названы my-plugin-da_DK.mo and my-plugin-da_DK.po. Чтобы узнать больше о кодах языков и стран, смотрите Установка WordPress на вашем языке.

  • Для WordPress 2.6 и выше третий параметр — это каталог, содержащий MO-файл, относительно каталога плагинов. Должен содержать слэш в конце. Если ваш плагин не нуждается в совместимости со старыми версиями WordPress, оставьте второй параметр пустым.
  • Для версий ниже, чем 2.6, второй параметр должен быть каталогом, содержащим MO-файл, относительно ABSPATH. Третий параметр должен быть пустым.

Для тем процесс на удивление похож:

Вызывайте это в файле functions.php и этот вызов будет искать в вашем каталоге темы файл locale.mo и загружать его (где locale — это текущий язык, например pt_BR.mo).

Внимание:

  • Называйте ваш MO-файл locale.mo (например, mo)
  • НЕ называйте ваш MO-файл my_theme-da_DK.mo

Перевод метаданных

Если вы добавите следующую строку в заголовок плагина или темы, где располагается имя плагина или темы, WordPress должен интернационализировать мета-данные вашего плагина или темы при отображении такового в админ-панели:

Пометка строк текстовым доменом

Все правила выше применимы и здесь, но есть и дополнительное. Вы должны добавлять ваш домен в качестве аргумента во все gettext-вызовы __, _e и __n, в противном случае, перевод осуществлен не будет.

Примеры:

  • __(‘String’) должно стать __(‘String’, ‘text_domain’)
  • _e(‘String’) должно стать _e(‘String’, ‘text_domain’)
  • _n(‘String’, ‘Strings’, $count) должно стать _n(‘String’, ‘Strings’, $count, ‘text_domain’)

Вручную делать это довольно трудоемко, поэтому автоматизируйте этот процесс:

— Если ваш плагин зарегистрирован в официальном репозитории, заходите на страницу администрирования и пролистайте до Добавить домен в вызовы Gettext.

или

— скачайте скрипт add-textdomain.php и запустите его так:

После выполнения этого во все вызовы функций gettext во всех файлах будет добавлен домен.

Перевод плагинов и тем

POT-файлы

Первый этап — сгенерировать .pot для вашего плагина или темы. Это делается с помощью утилиты xgettext, как части функциональности gettext. Если вы хотите сгенерировать файл на сервере, вы должны предварительно установить пакет gettext. Иначе говоря, это нужно, если вы хотите пользоваться в WordPress функциями интернационализации. Если ваш плагин зарегистрирован в официальном репозитории, для генерации файла используйте инструмент Admin->Generate POT file в админ-панели репозитория:

pot-file

Использование инструментов интернационализации.

Скачайте каталог инструментов интернационализации WordPress с SVN следующим образом:

Учтите, что скрипт ожидает, что будет доступна папка wp-includes/pomo/ в каталоге src относительно корневой папки инструментов. Другими словами, если каталог инструментов — это подкаталог папки WordPress, скрипт makepot.php будет искать ../../src/wp-includes/pomo/ (таковой будет иерархия файлов, если проверить все дерево каталога). Также может понадобиться сделать softlink на src из корня WordPress:

(Для того, чтобы узнать больше о SVN, см. использование Subversion.)

Теперь запускайте скрипт makepot.php вот так:

В качестве Target может быть wp-plugin для плагина и wp-theme для темы. Пусть directory будет полным (абсолютным или относительным) путем к каталогу cq. theme вашего плагина. Также можно запускать скрипт из каталога theme/plugin. Параметр output_file — опциональный, его значение по умолчанию — plugin-slug.pot в текущем каталоге.

Например:

Проверьте, появился ли файл .pot в каталоге.

Если вы включите .pot-файл в ваш плагин или тему, вместо того, чтобы предоставлять только .mo (или .po)-файлы, будущим переводчикам вашего плагина/темы будет легче начать перевод.

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

Если вы используете Grunt в вашей теме или плагине, можно использовать плагин grunt-pot авторства Стефана Харриса для генерации .pot-файла. См. этот сайт для пояснения, как интегрировать его в ваш проект.

Примеры содержимого

Каждая строка для перевода форматируется таким образом:

PO-файлы

Каждый переводчик берет .pot-файл WordPress и переводит секцию msgstr на его родной язык. В результате получается .po-файл такого же формата, как и .pot-файл, но с переводами и некоторыми специальными заголовками.

MO-файлы

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

Если у вас множество .po-файлов для преобразования за один раз, можно использовать пакетную обработку. Например, используя bash-команду:

Полезные вопросы

Ниже предоставлю список полезных вопросов и ответов по этой теме:

Источник: wordpress.org

 


Будь первым кто прокомментирует статью.

Добавить комментарий

Войти с помощью: