В этом посту я покажу вам простой и полностью рабочий способ создания перевода для своей WordPress-темы или плагина. Также вы сможете переводить темы и плагины других разработчиков.
Исходный код мы переводить не будем! Вообще, это непрофессионально и так делают те, кто только начинает осваивать WordPress.
Если же вам сразу хочется приступить к практике, то могу порекомендовать вам два видеоурока, один – про локализацию темы WordPress, другой – про локализацию плагина.
Перед тем, как создавать перевод, убедитесь, что всё, что нужно переводить в вашем плагине или в теме заключено в специальные функции перевода, вот эти функции:
Кроме того, часть этих функций даже есть уже со встроенной очисткой данных:
Итак, допустим в коде у нас есть текст «Hello World!» и нам нужно перевести его в «Привет, мир!», тогда:
echo __( 'Hello World!', 'truemisha' );
Второй аргумент функции, «truemisha» — это название перевода, может быть произвольным (главное, чтобы он совпадал с аналогичным параметром при подключении файлов перевода), также обычно совпадает с названием директории темы или плагина. Этот параметр не обязателен, если его не указывать, то для перевода будут задействованы стандартные языковые файлы, те, которые используются для перевода самого движка, админки. Понятное дело, что в стандартных языковых файлах может и не быть перевода тех строк, которые будут в нашей теме или в плагине.
Такой же пример, но с использованием функции _e():
_e( 'Hello World!', 'truemisha' );
Итак, если нам надо вывести переведенную строку, мы используем функцию _e(), а если нужно записать строку в переменную или задействовать в качестве аргумента какой-либо функции, то используем __().
Кроме того, если выводимый код нуждается в очистке, то наша строчка кода снова видоизменяется:
<h1><?php esc_html_e( 'Hello World!', 'truemisha' ); ?></h1>
Итак, подготавливаем свою тему или плагин к переводу и переходим к следующему шагу.
Нам понадобится программа Poedit, бесплатная версия вполне подойдет.
Открываем программу и переходим в Файл > Создать (File > New), после чего нам будет предложено выбрать язык перевода.
Переходим в Каталог > Свойства (Transations > Properties), и у нас откроется три вкладки с настройками. Сначала заполняем первую вкладку. Каких-либо особых требований к ее заполнению нет, главное, чтобы кодировка была UTF-8. Вот как получилось у меня:
Далее – вкладка «Ключевые слова исходных файлов». Указываем тут все используемые при интернационализации функции. Затем нажимаем ОК.
Вот чуть более подробный их список:
__ _e _n:1,2 _n_noop:1,2 _x:1,2c _ex:1,2c _nx:4c,1,2 esc_attr__ esc_attr_e esc_attr_x:1,2c esc_html__ esc_html_e esc_html_x:1,2c
Думаю сейчас не помешает совсем немного объяснений.
:1,2
, что означает, что первый и второй параметр функции должны быть переведены.:1,2c
, что означает, что первый параметр функции должен быть переведён, а второй параметр является контекстом перевода.:4c,1,2
, что значит, что четвёртный параметр функции является контектом, а первый и второй должны быть переведены.Далее – вкладка «Папка с исходными файлами». Новая версия Poedit вообще не позволяет делать в ней никаких изменений пока мы не сохраним файл. Ну окей.
languages
.{название перевода}-{название языка}
, например для русского перевода: truemisha-ru_RU.po
и truemisha-ru_RU.mo
. Для тем же просто ru_RU.po
и ru_RU.mo
Окей, про {название перевода}
я уже писал ранее в этом посту, но откуда брать {название языка}
? Всё просто — откройте файл wp-config.php
и посмотрите значение константы WPLANG
Наконец-то теперь мы можем настроить последнюю оставшуюся вкладку. Указываем там либо точку, либо нажимаем кнопку плюсика и выбираем папку со своей темой или плагином.
Почти готово – сохраняем. Затем нажимаем кнопку «Обновить» либо Каталог > Обновить из исходного кода. Та-дам, в окне программы должны появиться все строки, доступные для перевода.
Переводим, сохраняем.
Если мы переводим тему, открываем её файл functions.php
и добавляем туда следующий код:
add_action('after_setup_theme', 'true_load_theme_textdomain'); function true_load_theme_textdomain(){ load_theme_textdomain( 'truemisha', get_template_directory() . '/languages' ); }
Первый аргумент функции load_theme_textdomain() — это название перевода, оно же используется в функциях __() и _e(), второй аргумент — путь к директории с языковыми файлами. Функция get_template_directory() используется для получения пути к директории текущей темы.
Если мы переводим плагин, то открываем главный исполняемый файл плагина и вставляем туда:
add_action( 'plugins_loaded', 'true_load_plugin_textdomain' ); function true_load_plugin_textdomain() { load_plugin_textdomain( 'truemisha', false, dirname( plugin_basename( __FILE__ ) ) . '/languages/' ); }
Как видите, для плагинов мы используем другую функцию — load_plugin_textdomain(). Её единственное отличие — это второй аргумент, который не используется в новых версиях WordPress и всегда должен быть равен false
. А для получения пути к директории плагина, воспользуемся plugin_basename().
Хотите разобраться с локализацией на реальных примерах? Тогда вот вам два видеоурока, один – про локализацию темы WordPress, другой – про локализацию плагина.
Допустим, мы выводим количество товаров в своей теме интернет-магазина. Как сделать так, чтобы в зависимости от количества товаров, выводилась соответствующая форма слова, например: 1 товар, 2 товара, 5 товаров?
На самом деле в свежих версиях Poedit уже практически всё сделано за нас. Во вкладке свойств перевода при выборе языка уже будет вставлено соответствующее выражение для обработки форм множественного числа.
Хотя у нас есть возможность его изменить.
По умолчанию для русского языка это:
nplurals=3; plural=(n%10==1 && n%100!=11) ? 0 : ((n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20)) ? 1 : 2);
Это выражение позволяет использовать три формы множественного числа (именно столько используется в русском языке.
Вот выражение для двух форм (английский язык например) :
nplurals=2; plural=n != 1;
Для четырех форм (словенский язык) :
nplurals=4; plural=n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3;
Теперь в этом же окошке переходим во вкладку «Ключевые слова исходных файлов» и дописываем туда функцию _n() следующим образом: _n:1,2
. Вот что получится:
Возможно вы ещё захотите использовать функцию _nx().
Непосредственно в файлах темы или плагина функция используется в комбинации с PHP-функцяими sprintf()
или printf()
. Например:
$products = 4; $text = sprintf( _n( '1 product', '%s product', $products, 'truemisha' ), $products ); echo $text;
Окей, теперь сохраняем и обновляем файл перевода. Как видите, для задания форм слова у нас сейчас имеется три поля, указываем в них: 1 товар
, %s товара
и %s товаров
соответственно.
Вставляем этот код в functions.php
текущей темы. Затем, если в URL дописать что-то типа ?lang=ru_RU
, то язык темы изменится для страницы, на которой вы находитесь.
add_filter( 'locale', 'true_localize_theme' ); function true_localize_theme( $locale ) { if ( isset( $_GET[ 'lang' ] ) ) { return esc_attr( $_GET[ 'lang' ] ); } return $locale; }
Неправильно:
$result = __( $string, 'truemisha' ); $result = __( "You have $number bananas", 'truemisha' ); $result = __( 'You have 5 bananas', $domain ); $result = __( 'You have 5 bananas', PLUGIN_DOMAIN );
Правильно:
$result = __( 'You have 5 bananas', 'truemisha' );
Неправильно:
$result = __( 'You have ', 'truemisha' ) . $number . __( ' bananas', 'truemisha' );
Правильно:
$result = sprintf( __( 'You have %d bananas', 'truemisha' ), $number );
Так как вы никогда не скажете «У тебя 1 бананов», то даже правильнее будет использовать функцию _n(), например:
$result = sprintf( _n( 'You have %d banana.', 'You have %d bananas.', $number, 'truemisha' ), $number );
Зачем давать переводчику возможность изменять разметку нашей темы? Теги HTML должны быть отделены от переводимых строк везде, где это возможно.
Неправильно:
$result = sprintf( __( '<h3>You have %d bananas</h3>', 'truemisha' ), $number );
Правильно:
$result = '<h3>' . sprintf( __( 'You have %d bananas', 'truemisha' ), $number ) . '</h3>';
Конечно же, не обязательно всё делать вручную (хотя я почти всегда делаю), существуют плагины, позволяющие автоматически из админки генерировать .po- и .mo-файлы, один из таких плагинов — Codestyling Localization.
Скачать и установить его на сайт вы можете через меню Плагины > Добавить новый.
Чтобы оставить комментарий, пожалуйста, зарегистрируйтесь или войдите.
Добрый день! Подскажите, пожалуйста, что делать, если разработчики моей темы и плагинов не используют plurals. На мои стенания вежливо отвечают, что это потребует больших изменений кода. :)
Могу ли я, не прибегая к хардкодингу, самостоятельно добавить формы множественного числа? Хуки, плагины...
Добрый день!
Скиньте им ссылку на эту статью и скажите, что вы знаете, что больших изменений кода это не потребует (они просто не хотят заморачиваться) и заплатите им вдвое меньше, если они это не сделают :)
Не знаю, зависит от того, насколько хорошо вы разбираетесь в PHP.
Здравствуйте как понять название версия проекта это надо указывать доменое имя что ли
Здравствуйте!
Там можно что угодно указать, это ни на что не повлияет. Например «Сайт на WordPress», версия 1.0.
Здравствуйте, помогите, если сможете.
Года 2 назад удачно перевел шаблон. Использовал в настройках это (причем на тот момент везде рекомендовалось использовать именно так)
В шаблоне было так
С легкостью перевел так
т.е использовалось именно числительное, включая 0, т.е нет комментариев. А сейчас в шаблоне попалось
PoEdit выставил такие настройки
3 дня уже сижу и не могу заставить работать правильный перевод
Добрый день!
Тот код, который вы использовали в самом начале — неверен. В русском языке только 3 формы множественного числа.
Попробуйте использовать стандартный PoEdit-овский код, а затем проверьте заново все переведённые строки.
Благодарю.
Полезненько.
А всем ли плагинам можно прикрутить перевод? Было уже 3 плагина, которые ни в какую не хотят воспринимать перевод. Побаловал всеми известными способами, в том числе описанный вами, но результата никакого.
А Poedit видит вообще строки для перевода?
Конечно видит, а как по другому? 2 плагина правда сканировал и создавал файл локализации сам, а 3-й был уже в плагине. А перевод никак не работает.
Если PoEdit видит, то возможно где-то в подключении ошибка.
Вот это да.... я именно так и думал. Перепробовал кучу способов, по аналогам с разных плагинов и всё в пустую.
Помогите с переводом плагина UserPro.
Не получается перевести меню плагина,а именно не получается перевести код,типа:
$userpro_fields['user_pass'] = array(
'_builtin' => 1,
'type' => 'password',
'label' => 'Password',
'help' => 'Your password must be 8 characters long at least.'
);
перевожу фразы 'Password' и 'Your password must be 8 characters long at least.' но в самом плагине ничего не меняется.Что может быть!?Аналогичных словосочетаний в папке с плагином больше нет!
Привет!Для начала,удалите данный плагин,потом необходимо зайти в phpmyadmin и удалить все параметры UserPro.Затем,просто скачайте данный плагин с сайта
и установите его.Кстати, работу переведенного плагина UserPro можете увидеть на сайте по этой ссылке.
Добрый день
создал мо и ро
загрузил в папку
прописал в фанкшн
перевод не хочет появляться
Добрый день!
Вы мне абсолютно никакой информации не дали, чтобы я смог вам помочь.
Миша, помогите сориентироваться. Вот сколько не пытался создать pot файл - не получается. Вроде бы всё делаю по инструкции, но всё время получаю сообщение, что poedit не нашёл никаких файлов в просканированных папках.
Верно ли я понимаю, что в указанной мной папке программа должна сканировать файлы php на наличие в них текста для перевода, и при нахождении таковых, вытаскивать их в отдельный файл? И если моё понимание верно, то, что может быть причиной такой ошибки?
Pot файл пытаюсь сделать для форума simple-press. В ключевые слова исходных файлов, прописываю среди прочего и __sp() (именно такой вид имеют в simplepress фрагменты текста)
А куда вы сохраняете pot файл?
Есть папка в папке wp-content - sp-resources. Она создаётся после установки плагина форума simplepress. В ней содержатся файлы форума. Среди прочего, например и папка \forum-themes\default\templates, где содержатся файлы, отвечающие за внешний вид форума и текстовые элементы. В этой папке содержатся php файлы. Я скачиваю папку sp-resources со всем содержимым на рабочий стол, после чего запускаю poedit, выполняю описанные Вами выше действия и пытаюсь сохранить pot файл в папке \sp-resources\forum-themes\default\templates\..
Далее программа думает несколько секунд, а потом выдаёт сообщения: Poedit не нашёл никаких файлов в просканированных папках. Элементы каталога, возможно, неверны.
А вы проверяли, есть ли там вообще строки, подготовленные к переводу?
Ну, если я что-нибудь в чём-нибудь понимаю, то да. Есть. Вот пример строки из одного файла в данной папке:
sp_ListTopicName('', __sp('Browse the thread %NAME%'));
Это __sp('Browse the thread %NAME% ведь то, что нужно?
Похоже, что __sp() это функция уже вашего плагина. А вы указали её в настройках PoEdit ?
Да. Указал. Вообще проблему с переводом данного плагина уже решил, добыв .po файл от последней версии и переведя его. Но хотелось бы всё таки понять источник сложностей в данном вопросе. А то в своё время пришлось вручную искать недостающие строки в исходных файлах и добавлять в .po файл. Удовольствие то ещё.
Приветствую.
Отличная статья. Узнал для себя массу интересного, хотя данной программой Poedit пользовался и раньше для переводов шаблонов wordpress. Правда, у меня на днях возникла одна проблема. Есть шаблон, разработчик предусмотрел, что понадобится его локализация и через админку можно ее включить. Внешняя сторона шаблона переводится за секунды. С одной стороны, чего еще желать. Но! Использую я или не использую Poedit, сама админская часть не желает переводиться.
Разумеется, методом научного тыка я раскопал где именно прячутся эти файлы, но, переводить руками без Poedit довольно проблематично и бессмысленно, так как после обновления WP, все эти переводы слетят к чертям. Так вот, как можно было бы решить данную проблему? Что скажите?
Привет!
В плагинах очень часто бывает, что для админки отдельное значение textdomain.
Михаил, а можно несколько по подробнее? Если не сложно, конечно.
А можете прислать кусочек кода из такого непереведённого файла? Чтобы была строка и функция, в которой она находится.
Приветствую, Михаил.
Ну вот, например, после того как исправил в .php Modul 1на Модуль 1 - на сайте он разумеется поменялся. Но до поры до времени, после обновления WP - слетит же все..
Это означает, что админка не поддерживает локализацию :)
Блин.. Печаль то какая и грусть вселенская ..
А что ни как это дело не поправить? :)
Написать автору :) Или через jQuery изощриться.
Окей :)
Попробую через jQuery. Получиться отпишусь ;-)
Миш, а не подскажешь, как безболезненно заменить перевод ядра, что бы он не потерялся при обновлении. Например, фразу:
"Подсказка: Пароль должен состоять как минимум из двенадцати символов. "
(На самом деле дефолтная длинна не ограничивается вообще и к тому же может меняться плагинами, но вот фраза вылазит).
Перевод ядра. Слушай, я с этим не сталкивался, но думаю что как-то должно быть можно. Ну или на худой конец через jQuery :)
Приветствую! В который раз нахожу ответы на Вашем сайте, за что огромное спасибо!
Не подскажите еще. а как перевести фразу встроенные в js ?
Привет,
Вам нужна функция wp_localize_script().
Хотел избавиться от плагина Loco Translate. Почитал Вашу статью.... оставил плагин) Не сильно и мешает)))
Ахах 😁
Целый день потратила, чтобы написать плагин и сделать для него файлы перевода (через Poedit), там легкие изменения в программе есть. Теперь нужно самому дописывать расширение .pot к названию при сохранении файла. Но остальное получилось! (Делала в первый раз, все по Вашей, Мишенька, инструкции). Спасибо за чистый код. Отлично сработал на теме Flatsome. Продолжайте свое дело! Вы несете людям радость от полученного результата. По крайней мере для меня, сегодня, так точно. Пусть умножается. Намасте.))
Очень и очень рад! 🙂Это вам спасибо!
А как быть с wp_ajax?
Есть обработчик формы, который добавляется в wp_ajax, пример:
Перевод текста ошибки будет не корректный, будет переводится только на язык дефолтного сайта.
Пробовал переопределить язык через фильтр "add_filter('determine_locale', fn...), получив перед эти текущую локаль через "get_locale()", но get_locale() - возвращает локаль дефолтного сайта. Используется WP Multisite и loco translate.
Мне не приходилось работать с loco translate, но возможно как вариант можно попробовать на уровне JavaScript сделать перевод при помощи например wp_localize_script()