Несмотря на многочисленные статьи про перевод WordPress, лишь немногие пользователи вдаются в детали того, как это делается.
Что происходит, когда вы меняете что-либо в коде? Что происходит, когда вы добавляете новые строки? Что происходит, когда вы обновляете плагин до новой версии?
На эти вопросы я дам вам ответ в представленной статье. Я покажу вам, как перевести новые плагины и обновления на любой язык.
Давайте приступим к этому!
Создание плагина
Первое, что вам нужно сделать – это создать плагин. Если у вас уже имеется свой плагин – прекрасно! Если нет, то в таком случае вы можете воспользоваться нашим масштабным руководством по созданию плагинов. Если вам требуется быстрый пример создания плагина, то читайте далее.
Все, что мы сделаем – это просто добавим некоторый мотивационный текст в хэдер. Представьте, что это просто плагин Hello Dolly, только с явным мотивационным текстом, а не с лирикой.
Во-первых, создайте папку в каталоге с вашими плагинами и назовите ее wp-admin-motivation. Затем создайте файл в этой папке под названием wp-admin-motivation.php. Внесите в этот файл следующий код:
<?php /* Plugin Name: Admin Motivation Plugin URI: http://danielpataki.com Description: Shows motivational messages in the admoin bar Author: Daniel Pataki Version: 1.0 Author URI: http://danielpataki.com Text Domain: wp-admin-motivation */ function get_motivation_text() { $motivation = array( 'You are awesome', 'This website is boss', 'You look great today', 'Your earlobes are well rounded, good job!' ); shuffle( $motivation ); return $motivation[0]; } add_action( 'admin_notices', 'show_motivation_text' ); function show_motivation_text() { $text = get_motivation_text(); echo "<p id='wp-admin-motivation'>$text</p>"; } add_action( 'admin_enqueue_scripts', 'motivation_assets' ); function motivation_assets($hook) { wp_enqueue_style( 'motivation-styles', plugin_dir_url( __FILE__ ) . 'styles.css' ); }
Первая функция get_motivation_text() содержит в себе массив мотивационных строк. Массив перемешивается, после чего выводится первый его элемент. Это эффективнее, чем использовать рандомайзер; результат этой функции – случайным образом выбранный пункт из массива.
Затем мы подцепляем функцию show_motivation_text() к хуку admin_notices. Функция получает случайный мотивационный текст и выводит его в элементе p с id «wp-admin-motivation». На данном этапе наш текст будет видимым; давайте позиционируем его справа от вкладок с настройками экрана/справкой при помощи CSS.
Плагин Hello Dolly добавляет CSS, просто выводя его в хэдере. Это не самый лучший способ выполнения вещей, поэтому давайте вместо этого поставим в очередь таблицу стилей. Делается это путем подцепления функции motivation_assets() к admin_enqueue_scripts и постановки в очередь таблицы стилей.
Таблица стилей позиционирует текст и решает проблемы с RTL языками.
#wp-admin-motivation { float: right; padding-right: 15px; padding-top: 7px; margin: 0; font-size: 11px; } .rtl #wp-admin-motivation { float: left; padding-left: 15px; }
Единственная проблема нашего плагина – он работает только с английским языком. Если вы хотите использовать другой язык, вам придется создавать точно такой же плагин, изменив его строки на нужный язык. Выглядит это лишним шагом, поэтому давайте пойдем более эффективным путем.
Интернационализация плагина
Интернационализация плагина по существу означает – сделать его готовым к переводу. В процессе интернационализации все строки, которые можно перевести, обертываются в специальные функции, используемые впоследствии для загрузки корректных переводов.
Есть масса функций интернационализации, однако для нашего простого плагина мы рассмотрим только одну из них, а про остальные поговорим позже, как только усвоим данный пример.
Функция, которую мы будем использовать — __(). Эта функция принимает два аргумента: текст для перевода и текстовый домен. Все это в действии выглядит так:
<?php $greeting = __( 'Hello There!', 'text-domain' ); ?>
Функция возвращает перевод для отмеченной строки. Если перевода нет, возвращается исходная строка.
Функция использует текущий язык для определения необходимого перевода. Вы можете менять язык в WordPress в разделе Параметры. Тот язык, который выбран в этом разделе, будет применяться ко всем переводам.
Текстовый домен – заключительный «кирпичик» в данной функции. Текстовый домен – это способ сгруппировать переводы. Тема, запущенная у вас, будет иметь свой собственный текстовый домен, как и все ваши плагины. Это позволяет их дифференцировать.
Обратите внимание, что для плагинов текстовый домен – это название папки плагина. В нашем примере это означает, что текстовый домен должен быть wp-admin-motivation. Чтобы интернационализировать наш плагин, мы должны обернуть строки в функцию __().
$motivation = array( __( 'You are awesome', 'wp-admin-motivation'), __( 'This website is boss', 'wp-admin-motivation'), __( 'You look great today', 'wp-admin-motivation'), __( 'Your earlobes are well rounded, good job!, 'wp-admin-motivation')' );
Применение переводов
Мы пометили строки, которые можно перевести, однако пока у нас нет никаких переводов. Нам нужно сообщить WordPress, где искать переводы нашего плагина. Стандарт – директория lang в папке с плагином. Создайте ее и используйте следующий код в основном файле плагина, чтобы сообщить WordPress о том, где искать переводы.
add_action('plugins_loaded', 'wan_load_textdomain'); function wan_load_textdomain() { load_plugin_textdomain( 'wp-admin-motivation', false, dirname( plugin_basename(__FILE__) ) . '/lang/' ); }
Функция load_plugin_textdomain() – ключевая здесь, ее нужно вызвать в функции, подцепленной к plugins_loaded. Первый аргумент – это текстовый домен, о котором мы уже говорили выше, второй – в данный момент устарел, третий – расположение папки с языками.
Наши файлы переводов будут носить название [plugin-name]-[locale].mo. Чуть позже я покажу вам, как создать их; пока что просто запомните, где они находятся. В нашем примере файл с немецким переводом будет называться wp-admin-motivation-de_DE.mo. Вы можете прочитать про языковые коды стран, если вы не знаете их.
Если бы у нас были языковые файлы на данном этапе, то все бы работало просто великолепно. Последний шаг, который нужно сделать – это создать переводы.
Создание перевода
Есть масса способов создания переводов, однако конечный результат всегда будет одним и тем же. Вы получите два файла: файл po и файл mo. Po-файл – это человекочитаемый файл переводов. Вы можете открыть его в любом текстовом редакторе и отредактировать. Mo-файл – это po-файл, который был сконвертирован в машиночитаемый формат. Он гораздо меньше по размеру, но при этом абсолютно нечитабельный.
Ниже приведен пример непереведенного файла po. Как вы можете видеть, в нем содержится некоторая основная информация о переводе, переводчике и проекте, далее следует список переводимых строк и их будущих переводов.
msgid "" msgstr "" "Project-Id-Version: WP Admin Motivation 1.0.0\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2015-04-27 13:09+0100\n" "PO-Revision-Date: 2015-04-27 13:09+0100\n" "Last-Translator: Daniel Pataki <[email protected]>\n" "Language-Team: Daniel Pataki <[email protected]>\n" "Language: Hungarian\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Poedit-KeywordsList: __;_e\n" "X-Poedit-Basepath: .\n" "X-Poedit-SearchPath-0: ..\n" #: ../wp-admin-motivation.php:20 msgid "You are awesome" msgstr "" #: ../wp-admin-motivation.php:21 msgid "This website is boss" msgstr "" #: ../wp-admin-motivation.php:22 msgid "You look great today" msgstr "" #: ../wp-admin-motivation.php:23 msgid "Your earlobes are well rounded, good job!" msgstr ""
Переводимый участок имеет следующий вид:
#: path-to-file:line-number msgid "string to translate" msgstr "translation goes here"
Вручную обрабатывать строки достаточно сложно, поэтому их легче всего перевести в отдельной программе. Как только ваш плагин будет в хранилище, вы сможете воспользоваться администраторскими инструментами, которые позволят вам сгенерировать PO-файл, однако вы можете также создать его с помощью бесплатного инструмента Poedit.
Скачайте и запустите Poedit, щелкните по New и затем выберите New Catalog. В окне, которое появится, введите всю необходимую информацию. Вам не нужно в данный момент переживать по поводу набора символов или форм множественного числа, просто укажите базовую информацию.
Переключитесь на Source paths и задайте необходимые пути. Большое поле под названием Paths сообщает Poedit о том, где искать переводимые строки относительно основного пути (Base Path).
Мы поместим наши переводы в подкаталог нашего плагина. Это означает, что у нас есть два варианта:
- Задать базовый путь как «../» (родительский каталог), а путь в разделе путей задать как «.» (текущая директория).
- Задать базовый путь как «.» (текущая директория), а путь в разделе путей задать как «../».
В первом случае мы сообщаем Poedit, что наш код находится в родительском каталоге языковой папки. Poedit должен будет перейти к родительскому каталогу и затем впоследствии искать там нужную директорию (поскольку используется «.» в секции путей).
Во втором случае мы сообщаем Poedit, что наш текущий каталог – тот, в котором находится языковой файл. Однако файлы, которые нам нужно проверить, находятся в предыдущей директории (нужно перейти на один уровень назад).
Любой способ хорош, однако я считаю, что первая версия в семантическом плане более корректна, несмотря на то, что сам я чаще использую второй вариант для своих плагинов.
Следующий шаг: задание ключевых слов в секции «Sources keywords». Здесь мы определяем имена функции переводчика. В нашем случае мы задаем одну функцию — __. Скорее всего, вам понадобится добавить в это поле как минимум 2-3 функции.
Затем Poedit просканирует файлы и выдаст все переводимые строки. Они будут организованы в виде списка. Перевод можно будет задавать в нижней области экрана.
Как только вы сделаете переводы, вам нужно будет сохранить файл. Poedit автоматически сгенерирует для вас MO файл. По умолчанию имя файла будет следующим: [plugin-name]_[locale].mo. Имя файла PO не так важно, хотя для удобства я бы дал ему то же самое название.
В моем случае я перевел файл на венгерский, поэтому имя файла следующее: wp-admin-motivation-hu_HU.mo. Как только этот файл появится в соответствующей папке, плагин сможет отразить указанный текст на венгерском языке, если сборка WordPress использует венгерский язык.
Управление переводами
Обновление переводов – не такая сложная вещь. PO-файл содержит расположение переведенного текста, а также номер строки, однако эти данные не учитываются WordPress при использовании файла. Расположение текста и номер строки указываются для переводчика, чтобы он мог найти строку в случае необходимости.
Если вы просто изменяете код, не меняя контент переводимых строк, вам не нужно будет обновлять языковые файлы. Обычно я создаю файл POT, который обновляется всякий раз, когда я обновляю плагин, даже если строки не были изменены.
POT-файлы – это те же PO-файлы, но не содержащие каких-либо реальных переводов – они просто являются шаблонами. Пока шаблон обновлен и содержит правильную позицию для каждой строки, можно легко выполнять новые переводы.
Если вам нужно обновить языковой файл, вам понадобится открыть его в Poedit и щелкнуть по иконке Update. Poedit уведомит вас, какие строки были изменены, а какие добавлены, и вы сможете затем отредактировать их при необходимости.
Прием переводов
Единственное, что меня несколько отпугивает (по крайней мере, поначалу меня это смутило) – то, как именно переводы добавляются к плагину. Если я скачиваю плагин, как я могу добавить к нему свой собственный перевод? Я думал, что этот процесс каким-то образом автоматизирован, как в случае с установкой плагина, однако это не так.
Если кому-то понравился ваш плагин, этот человек может вполне перевести плагин на свой язык, используя POT-файл плагина, после чего отправить результат разработчику. Разработчик затем добавляет перевод в папку lang, создает новую версию плагина и отправляет ее в директорию WordPress. Когда пользователь получает обновление, плагин автоматически переводится на нужный язык, если тот будет в языковой папке.
Все свои репозитории я размещаю на Github, что заметно упрощает отправку языковых файлов с помощью pull-запросов. Мне нужно лишь нажать на кнопку и создать новую версию для репозитория WordPress.
Расширенные переводы
Теперь вы знаете, как перевести основные строки с помощью функции __(), которая возвращает значение. В общей сложности существует 14 функций, которые вы можете использовать для точной настройки ваших переводов. Обычно хватает трех-четырех функций. Давайте рассмотрим самые популярные из них.
__()
Базовая функция, которая получает строку и возвращает ее перевод, если тот существует.
_e()
Функция делает то же самое, что и предыдущая, однако вместо возвращения результата просто выводит его.
_n()
Функция позволяет вам изящно обработать формы множественного числа. Требуется 4 параметра: форма единственного числа, форма множественного числа, само число, а также текстовый домен. Вот простой пример:
<?php $messages = get_message_count(); // Simple form $text = _n( 'You have one message', 'You have lots of messages', $messages, 'my-message-app' ); // Displaying the actual number $text = sprintf( _n( 'You have one message', 'You %s messages', $messages, 'my-message-app' ), $messages ) ?>
_x()
Цель этой функции состоит в том, чтобы предотвратить коллизии подобных слов. Если ваш плагин использует термин «пара» в смысле «несколько человек» и «пара» в смысле «сопряжение устройств по Bluetooth», могут возникнуть коллизии. В иностранном языке для этого одного термина могут использоваться два разных слова. _x() позволяет вам указать свое намерение.
_x( 'Pair', 'A pair of people', 'my-plugin-textomaind' ); _x( 'Pair', 'As in: pairing devices', 'my-plugin-textomaind' );
_ex() и _nx
Эти функции совпадают с _x() по своему действию, однако первая сразу выводит результат, а вторая позволяет вам добавить форму множественного числа.
Экранирование переводов
Есть семь функций, которые позволяют вам экранировать значение для безопасного использования в атрибутах и HTML. Названия этих функций говорят сами за себя, поэтому я не будут объяснять их работу:
- esc_attr__()
- esc_attr_e()
- esc_attr_x()
- esc_html__()
- esc_html_e()
- esc_html_x()
Noop переводы
Эти переводы несколько более сложные, поэтому вы можете прочитать про них в следующей статье Константина Ковшенина «Понимание _n_noop». Функции Noop в основном регистрируют строки множественного числа в POT-файле, однако не переводят их. Причина этого состоит в том, что число заранее неизвестно.
Из-за этого мы используем функцию noop и переводим фактическое значение позже. Эта функциональность нужна лишь в некоторых отдельных ситуациях – про них вы можете прочитать в статье по ссылке.
Вот сами функции:
- _n_noop()
- _nx_noop()
- translate_nooped_plural()
Перевод Javascript
Как быть, если у вас имеются некоторые строки, которые находятся в Javascript? В WordPress есть решение для этого: функция wp_localize_script(). Данная функция принимает три аргумента: хэндл скрипта, который вы хотите перевести, имя объекта, которое будет использоваться в скрипте, а также массив перевода. Пример:
add_action( 'admin_enqueue_scripts', 'motivation_assets' ); function motivation_assets($hook) { wp_enqueue_script( 'motivation-scripts', plugin_dir_url( __FILE__ ) . 'scripts' ); wp_localize_script( 'motivation-scripts', 'wma', array( 'section_title' => __( 'Today's motivation', 'wp-admin-motivation' ) )); }
Как только вы добавите здесь свои переводы, вы сможете их использовать в зарегистрированном JS файле. Вам нужно будет использовать имя объекта и ключи массива перевода:
jQuery.html( "<h2>" + wma.section_title + "</h2>" );
Заключение
Многие миллионы людей используют WordPress на своем собственном языке, так почему бы не поступить точно так же с нашими продуктами? Создать плагины, готовые к переводу, очень и очень просто, да и поддерживать их легко.
Помечая строки для перевода, а также создавая po/mo файлы, мы помогаем улучшить наш продукт.
Скачать плагин, который мы создали в этом руководстве, вы можете по следующей ссылке.
Теперь, когда вы знаете, как перевести плагин, почему бы не взять любой из них в хранилище плагинов и не перевести его?
Источник: premium.wpmudev.org/blog
А как перенoсить строки в Poedit ?
Перевел плагин. Создал файлы. Только плагин упорно не желает их подхватывать. В папке с плагином есть папка languages. Закинул туда. Не пашет. Создал папку lang. Тоже не берет. Измучался уже.
Тоже пытаюсь перевести, не думал, что это в первый раз так будет сложно :(
Спасибо, помогли.