В предыдущем посте я рассмотрел основы интернационализации WordPress (сокращенно i18n
); как установить локализованную версию WordPress и как легко преобразовать существующий сайт WordPress в локализованную версию.
В этой статье я собираюсь рассказать вам о процессе интернационализации плагинов WordPress. Процесс не сложный, и как только знания будут получены, вы сможете легко перевести ваши плагины WordPress на другие языки.
Разница между интернационализацией и локализацией
С годами разработчики склонны неправильно понимать значение этих терминов — Internationalization
и Localization
.
- Интернационализация — это процесс разработки вашего плагина, чтобы его можно было легко перевести на другие языки.
- Локализация описывает последующий процесс перевода интернационализированного плагина на новый язык.
Стоит отметить, что Internationalization
часто сокращается как i18n
(потому что между «i» и «n» есть 18 букв), а « Localization
сокращается как l10n
(потому что между «l» и «n» есть 10 букв) ».)
Зачем интернационализировать?
Ответ прост; WordPress используется во всем мире на разных языках. Когда плагины интернационализируются, они привлекают большую аудиторию из других частей мира, которая, очевидно, выиграет от использования плагина на своем родном языке.
Как разработчик, у вас может не быть времени на предоставление локализованных версий вашего плагина, потому что вы не говорите на других языках. Однако, когда вы интернационализируете свой плагин, вы оставляете дверь открытой для других, чтобы создать локализацию без необходимости изменения исходного кода.
Плагин Интернационализация
Теперь, когда мы знакомы с концепцией интернационализации и локализации плагинов, давайте погрузимся в процесс подготовки плагинов к переводу.
Установить заголовки перевода
Первый шаг для создания переводимого плагина — это включить заголовки перевода в заголовки плагина.
Заголовки перевода — это Text Domain
и Domain Path
к Domain Path
.
Text Domain
используется для обозначения всего текста, принадлежащего плагину.
Это уникальный идентификатор, который гарантирует, что WordPress сможет различать все загруженные переводы. Это увеличивает мобильность и играет лучше с уже существующими инструментами WordPress.
Текстовый домен должен соответствовать слагу плагина. Например, если ваш плагин представляет собой один файл с именем sample-plugin.php
или он содержится в папке с именем sample-plugin
текстовый домен должен быть sample-plugin
.
Примечание к текстовому домену
Текстовое доменное имя должно использовать тире, а не подчеркивание.
Помните, я сказал, что текстовый домен должен совпадать с слагом плагина? Это не может быть правдой в конце концов. Я провел быстрый эксперимент с одним из моих плагинов, а не слаг плагина, я использовал уникальный текст, и он работал без каких-либо проблем.
Мораль: убедитесь, что Text Domain
уникален, чтобы он не конфликтовал с другими плагинами.
Domain Path
— это папка, в которой WordPress будет искать файлы перевода .mo
.
По умолчанию WordPress ищет в каталоге плагинов файлы перевода для использования. Наличие файла перевода в корневой папке вашего плагина может дезорганизовать структуру вашего плагина.
Если вы хотите сохранить файлы перевода в папке, например; /languages
, вам нужно сообщить об этом WordPress с помощью заголовка « Domain Path
к Domain Path
.
Ниже приведен типичный заголовок плагина WordPress, включая перевод.
<?php /* Plugin Name: Enable Shortcode and PHP in Text widget Plugin URI: http://w3guy.com/shortcode-php-support-wordpress-text-widget/ Description: Enable shortcode support and execute PHP in WordPress's Text Widget Author: Agbonghama Collins Version: 1.2 Author URI: http://w3guy.com Text Domain: espw-plugin Domain Path: /languages/ */
Загрузить текстовый домен
Теперь мы будем использовать функцию load_plugin_textdomain (), чтобы сообщить WordPress о загрузке файла перевода, если он существует для языка пользователя.
Ниже приведен краткий обзор функций.
<?php load_plugin_textdomain( $domain, $abs_rel_path, $plugin_rel_path ) ?>
Первый параметр $domain
должен быть текстовым доменом; $abs_rel_path
устарел и должен быть установлен в false
; наконец, $plugin_rel_path
— это относительный путь к файлам перевода.
Если перевод MO файлов находится в собственной директории плагина, используйте следующее:
load_plugin_textdomain( 'espw-plugin', false, dirname( plugin_basename( __FILE__ ) ) );
Если перевод MO файлов находится в подкаталоге языков плагина. Используйте следующим образом:
load_plugin_textdomain( 'espw-plugin', false, dirname( plugin_basename( __FILE__ ) ) . '/languages/' );
Вы не просто вызываете функцию load_plugin_textdomain
, она должна вызываться в вашем плагине уже при действии plugins_loaded
например:
function load_plugin_textdomain() { load_plugin_textdomain( 'espw-plugin', FALSE, basename( dirname( __FILE__ ) ) . '/languages/' ); } add_action( 'plugins_loaded', 'load_plugin_textdomain' );
Глубокое погружение в плагин I18n
Теперь, когда заданы заголовок Text Domain и Domain Path, пришло время узнать, как интернационализировать плагин.
Этот сегмент учебника будет разделен на следующее:
- Перевод строк
- Использование заполнителей
- Перевод HTML
- Работа с множественным числом
- Неоднозначность по контексту
- Экранирование строк перевода
Обратите внимание: строка espw-plugin
будет использоваться в качестве текстового домена в этом руководстве.
1. Перевод строк
Чтобы сделать строку переводимой в ваш плагин, оберните исходную строку в вызов функции __()
следующим образом:
$text = __( 'Hello, SitePoint Readers!', 'espw-plugin' );
Если вы хотите отобразить строку в браузере, вместо языковой конструкции echo
используйте функцию _e
:
_e( 'Hello, SitePoint Readers!', 'espw-plugin' );
2. Использование заполнителей
Как разработчики PHP и WordPress, я предполагаю, что вы знаете, что такое placeholders
. Вы можете быстро просмотреть PHP-документацию sprintf и printf () для получения дополнительной информации.
Если вы используете переменные в строках, как в примере ниже, вы должны использовать заполнители.
echo 'Your city is $city.'
Правильный путь — использовать функцию printf()
следующим образом:
printf( __( 'Your city is %s.', 'espw-plugin' ), $city );
Просматривая код некоторых плагинов, размещенных в хранилище плагинов WordPress, я вижу такие вещи:
echo __('Your city is $city', 'espw-plugin');
_e('Your city is $city', 'espw-plugin');
Хотя теперь строки можно переводить, переменная PHP $city
также становится переводимой.
Это плохая практика, потому что переводчик может по ошибке изменить переменную или внедрить вредоносный код в базу кода плагина, что в конечном итоге приведет к неправильной работе плагина.
Функция sprintf
похожа на printf
в том, что они форматируют строку с использованием заполнителей, в то время как printf
выводит отформатированную строку, sprintf
возвращает строку.
Пример: следующий код присваивает отформатированную строку переменной $text
.
$text = sprintf( __('Your city is %s.', 'espw-plugin'), $city );
3. Перевод HTML
Включение HTML в переводимые строки зависит от контекста.
Примером является ссылка (отделенная от окружающего ее текста):
<div class="site-info"> <a href="http://wordpress.org/" >< ?php _e( 'Proudly powered by WordPress.', 'espw-plugin' ); ?></a> </div>
Другим примером является ссылка в абзаце (не отделенная от окружающего его текста):
<?php $url = 'http://example.com'; $link = sprintf( __( 'Check out this link to my <a href="%s">website</a> made with WordPress.', 'espw-plugin' ), $url ); echo $link; ?>
4. Работа с множественным числом
Строка, которая изменяется при изменении количества элементов, может быть интернационализирована с помощью функции _n()
.
Эта функция принимает 4 аргумента, а именно:
- Singular — форма единственного числа строки
- Множественное число — форма множественного числа строки
- Count — количество объектов, которое будет определять, следует ли возвращать форму единственного или множественного числа
- Text Domain — плагины текстового домена
Давайте посмотрим несколько примеров, чтобы понять, как работает функция _n()
.
На английском языке у вас есть "One comment"
и "Two comments"
. На других языках вы можете иметь несколько форм множественного числа.
Приведенный ниже код демонстрирует, как обрабатывать такой сценарий с помощью функции _n()
.
printf( _n( 'One comment', '%s comments', get_comments_number(), 'espw-plugin' ), number_format_i18n( get_comments_number() ) );
Пояснение кода приведенный выше код состоит из этих трех функций — printf
, _n
и number_format_i18n
.
Для облегчения ассимиляции код функции будет рассекан с объяснением каждого компонента функции.
_n( 'One comment', '%s comments', get_comments_number(), 'espw-plugin' )
Первым аргументом, передаваемым функции _n
является текст, отображаемый, когда количество комментариев является единственным.
Вторым является текст, отображаемый, когда количество комментариев больше одного.
Заполнитель %s
будет содержать значение number_format_i18n( get_comments_number() )
которое будет объяснено в ближайшее время.
Третий аргумент get_comments_number()
считается функцией, которая возвращает количество комментариев.
Если он возвращает 1
, первый аргумент One comment
выводится printf
противном случае возвращается второй аргумент %s comments
если он больше 1
.
Обратите внимание: заполнитель %s
заменяется целым числом, возвращаемым number_format_i18n( get_comments_number() )
которое является вторым аргументом, передаваемым printf
.
Наконец, четвертый аргумент — это текстовая область перевода.
Функция number_format_i18n()
конвертирует количество комментариев в формат, основанный на локали. Смотрите документацию для получения дополнительной информации.
Аналогично number_format_i18n()
является date_i18n, которая извлекает дату в локализованном формате на основе метки времени.
Все еще с функцией _n()
, ниже еще одна демонстрация того, как работает функция.
printf( _n( 'We deleted one spam message.', 'We deleted %d spam messages.', $count, 'my-text-domain' ), $count );
Если переменная $count
возвращает 1
, то текст We deleted one spam message
; но если оно больше 1
, We deleted %d spam messages
которые будут отображаться с заполнителем %d
замененным целочисленным значением $count
.
5. Неоднозначность по контексту
Иногда один термин используется в нескольких контекстах, хотя это одно и то же слово в английском языке, его нужно переводить по-разному в других языках.
Например, слово « Post
можно использовать как в качестве глагола, например "Click here to post your comment"
и в качестве существительного "Edit this post"
.
В таких случаях следует использовать функцию _x или _ex .
Он похож на __()
и _e()
, но имеет дополнительный аргумент — $context
.
_x( 'Post', 'noun', 'espw-plugin' ); _x( 'Post', 'verb', 'espw-plugin' );
Используя этот метод в обоих случаях, мы получим строку Comment
для исходной версии, но переводчики увидят две строки Comment
для перевода, каждая в своем контексте.
Когда строки, переводимые функцией _x()
анализируются с помощью инструмента перевода, такого как Poedit , аргумент context предоставляет подсказку переводчику в контексте, в котором использовалась строка / текст.
На немецком языке Post как существительное — Beitrag
а как глагол — verbuchen.
Ниже приведен скриншот Poedit, переводящего строку Post
на немецкий язык с квадратным скобкой контекста.
Пока _x()
возвращает переведенную строку, _ex()
отображает ее.
6. Экранирование строк перевода
WordPress имеет ряд функций для проверки и очистки данных .
Среди списка есть функции для экранирования текстов перевода — esc_html (), esc_html_e (), esc_html_x (), esc_attr (), esc_attr_e () и esc_attr_x (). Вы можете получить больше информации о каждой из этих функций на WordPress Codex.
Мне не нужно объяснять каждый из них, но они в основном избегают переводимых текстов.
Заворачивать
Одна из целей WordPress — упростить публикацию контента для пользователей по всему миру. Как разработчик плагинов, вы можете помочь еще больше упростить процесс публикации для пользователей, когда вы интернационализируете свои плагины.
Первая часть этого урока была по существу обо всем, что вам нужно знать о плагине i18n.
Заключительная часть будет посвящена тому, как подготовить перевод плагина, а также узнает, как локализовать плагин на новый язык.
Я надеюсь, что вы узнали что-то новое из этого урока.
Удачного кодирования!