Сегодня о том, как перевести дочернюю тему WordPress. Но сначала небольшое пояснение. Есть два похожих по смыслу понятия: это перевод WordPress и мультиязычность сайта на WordPress.
Присказка
Перевод WordPress – это процесс, благодаря которому Вы, скачав какой-либо плагин или тему, сделанные в другой стране, устанавливаете их, активируете и… видите всё на Вашем родном русском. WordPress содержит в себе возможности хранить несколько языков как для самого движка, так и для различных дополнений. Язык переключается в админке. Пошли в админку, сменили язык, увидели WordPress на другом языке.
Мультиязычность – это как бы следующий шаг. Мультиязычность позволяет любому пользователю (а не только Вам) менять язык «на лету». То есть, где-то на странице есть флажки или другой селектор – нажали нужный – язык сменился. Думаю, всем знакомо.
Идея построение мультизычного сайта заключается в том, чтобы использовать стандартную функциональность WordPress по хранению многих языков, и позволить любому пользователю просто сменять их одним щелчком, чтобы видеть сайт на родном языке.
Это всё преамбула. Теперь о том, какую задачу мне пришлось решать.
Постановка задачи
Делаю сайт на заказ. Сайт мультиязычный. Плагин, обеспечивающий эту мультиязычность нашёл давно, всё работает. По ходу дела возникает необходимость добавить подписи в подвал сайта, и нужно, чтобы они переводились на выбранный язык при его смене.
Тема у меня – Twenty Twelve, но поскольку я не люблю менять стандартное, то сделал себе дочернюю от неё, и все изменения вношу туда. Как сделать дочернюю тему я писал тут.
Поэтому возникла несложная задача добавления переводов к дочерней теме.
Задача действительно простая, но возникла масса вопросов и нюансов. Ответы на все я нашёл в просторах Интернета, но пришлось собирать по крупицам, потратив изрядно времени. Тогда я и решил написать статью, в которой всё было бы собрано вместе.
Ниже краткая инструкция. Не спрашивайте только «Почему?». Я сам не знаю. Просто так работает, и высоки шансы, что если Вы повторите, то и у Вас тоже будет.
Решение
Итак, идём по шагам.
1. Модификация кода страницы
Тут всё весьма прозрачно и этот этап хорошо описан в Интернете. Основная мысль: в том месте, где должен быть кусок текста, надо вставить функцию, которая будет выдавать этот кусок на текущем языке.
Например, чтобы получить такую строку:
Копирайт © "www.SocDyslexic.com", 2013. Все права защищены.
нужно написать такой HTML код:
Копирайт © "<a href="www.SocDyslexic.com">www.SocDyslexic.com</a>", 2013. Все права защищены.
а чтобы это ещё и переводилось, получится примерно такая конструкция:
<?php printf( '%1$s © "<a title="%2$s" href="%3$s">%4$s</a>", 2013. %5$s', __( 'Copyright', 'twentytwelvechild' ), __( 'Is dyslexic community', 'twentytwelvechild' ), esc_url( __( 'http://www.socdyslexic.com', 'twentytwelvechild' ) ), __( 'www.SocDyslexic.com', 'twentytwelvechild' ), __( 'All rights reserved.', 'twentytwelvechild' ) ); ?>
Не пугайтесь, это самый сложный вариант. К тому же всё прозрачно. После printf
идёт комбинация символов, в которой угадывается исходная строка, только вместо %n$s
надо вставить кусочки текста. Каждый кусочек можно найти ниже, а двойное подчёркивание – ни что иное, как вызов функции для перевода этого кусочка.
Впрочем, обо всём этом сами прочтёте в Интернетах, там много и подробно.
2. Созданиение PO или POT файла
Вот здесь возникли первые сложности. Этот файл должен хранить в себе информацию о том, что же надо переводить. Задача простая: в Ваших исходных кодах надо выявить все вызовы функций с кусочками текста и этот текст подготовить для перевода. Что создатели WordPress использовали для этого стороннюю технологию я понял быстро, а вот создать этот PO или POT файл не получалось.
Все пели дифирамбы редактору POEdit, поэтому я им и воспользовался. Признаюсь, восторга я не разделил, и без подсказки с задачей не справился. Установил программу, запустил, и не понял что же надо сделать. Программа мне предлагала создать некий каталог, но мне нужен был лишь PO файл!
Если коротко, то схема такая. Выбираете меню «Файл» – «Создать каталог…», заполняете поля как на картинках:
Во всех полях пишите что хотите, главное, чтобы в «Формах множественного числа» было nplurals=2; plural=n != 1;
– не спрашивайте почему!!!
Добавлено 13.10.2013:
Александр в комментариях пишет, что для русского языка следует использовать формулу nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100=20) ? 1 : 2;
Я ещё не успел проверить сам, но буду иметь в виду. Спасибо, Александр! Все читаем документацию по использованию gettext
!
На второй закладке делаем так:
Очень важно «Базовый путь» оставить одной точкой, а ниже в списке «Пути» добавить единственную строку с двумя точками. Я уже не первый десяток лет работаю с файловой системой и прекрасно знаю, что одна точка – это текущий каталог, а две точки – каталог уровнем выше. Но эта штука у меня отказалась кушать другие сочетания. Вернее, она кушала, но ничего не находила.
Наконец, на третьей закладке пишем:
Для ленивых (таких же как я) цитирую (всё равно придётся по одной переносить):
__ _e _n:1,2 _x:1,2c _ex:1,2c
Опять же, не спрашивайте почему тут такие строки!!!
Добавлено 13.10.2013:
Для другого плагина список пришлось расширить после того, как поиск не выявил всех констант для перевода. В таком варианте нашлось всё:
__ _e _n:1,2 _x:1,2c _ex:1,2c __ngettext:1,2 __ngettext_noop:1,2 _n_noop:1,2 _c _nc:4c,1,2 _nx:4c,1,2 _nx_noop:4c,1,2 esc_attr__ esc_attr_e esc_attr_x:1,2c esc_html__ esc_html_e esc_html_x:1,2c\n
После этого программа должна предложить Вам сохранить Ваш PO файл. Вот тут ещё один важный момент, связанный как раз со всеми этими точками. Вам нужно собрать все Ваши PHP файлы, в которых нужно искать строки для перевода в один каталог, допустим в
d:\source
а в нём создать ещё один, скажем, languages
:
d:\source\languages
и именно в него сохранить Ваш PO файл. Тогда две точки сработают правильно, и d:\source
будет «родительским» по отношению к languages
, в котором разместится PO файл. Если ничего не поняли – не переживайте, просто делайте:
Если Вы сделали всё правильно, то божественная программа POEdit просканирует Ваши PHP файлы, найдёт там всё, что нужно переводить и выдаст вам список. Вы должны справиться с переводом, там ничего сложного, поэтому картинку я не размещаю. Не забудьте сохранить результат!
3. Рассказываем теме, что теперь у неё есть переводы
Если Вы всё делали по моей инструкции, у Вас должен быть каталог
d:\source\languages
в котором должны появиться два файла с расширениями .po и .mo. Если у Вас нет диска «d», то Вам крупно не повезло! Шутка.
Теперь самое сложное (для меня оказалось): «подсунуть» эти два файла теме. В Интернетах Вы, наверняка, встретите предложения вставить в Вашу тему что-нибудь типа:
add_action('after_setup_theme', 'my_child_theme_setup'); function my_child_theme_setup() { load_theme_textdomain('mytheme', get_template_directory() . '/languages'); }
Первый законный вопрос, который должен возникнуть у Вас: «А куда?!». Отвечаю: в файл functions.php
. Могу успокоить: в отличие от header.php
, footer.php
и прочих пи-эйч-пи, ответственных за формирования частей веб-страницы, functions.php
можно спокойно добавить в дочернюю тему, и он не «перетрёт» родительский. То есть, добавленный в дочернюю тему header.php
замещает собой header.php
из родительской темы, а вот functions.php
– нет, он просто добавляется к родительскому (ну, или как-то так). Короче, создаём такой файл в своей дочерней теме и пишем туда указанный выше кусок кода. Не забываем про кодировку UTF-8!
Желающие могут убедиться, что работать оно не будет, куда бы они ни положили свои .po и .mo файлы, и как бы их ни назвали. Причин две.
Во-первых, для дочерней темы надо использовать load_child_theme_textdomain
, и это даже кое-где упоминается. А, во-вторых, get_template_directory
для дочерних тем ни фига не работает! Надо использовать get_stylesheet_directory
. Весь functions.php
для моей дочерней темы выглядит так:
<?php add_action('after_setup_theme', 'twentytwelve_child_setup'); function twentytwelve_child_setup(){ load_child_theme_textdomain('twentytwelvechild', get_stylesheet_directory() . '/languages'); } ?>
Кстати, Вы должны были заметить, что в моих кодах время от времени встречается константа «twentytwelvechild
«. Это так называемый домен. Чтобы переводчик WordPress знал, к чему относятся переводы. У каждого плагина, у каждой темы должен быть свой домен.
4. Размещаем .po и .mo в правильном месте
Мы близки к победе! Получившиеся у Вас файлы .po и .mo нужно назвать правильно. В отличие от локализации плагина, для темы (дочерней темы в том числе) их имя должно полностью совпадать с локалью (локалем?). Для русского языка это ru_RU – Вы поймёте, о чём я. Переименовываем файлы в ru_RU.po
и ru_RU.mo
и копируем их в тот каталог, который Вы указали в параметрах функции load_child_theme_textdomain
. В нашем случае это languages. У меня полный путь такой:
wp-content/themes/twentytwelve-child/languages
Только если Вы их просто туда скопируете, то ничего не заработает. Причина проста: добавленный в functions.php
кусок кода срабатывает после установки темы. А у меня моя дочерняя тема была установлена давно, поэтому пришлось собрать все её файлы в один каталог, заархивировать его в ZIP архив, тему удалить и снова установить из архива. Кто знает как запустить одну функцию вручную, может попробовать без переустановки темы.
Да, в общем и целом .po файл Вам на сервере не нужен. Все переведённые данные хранятся в .mo. Но я его всё равно скопировал, чтобы .mo там одному скучно не было!
Ну, вроде всё! Должно работать!
В заключение
Потратил на эту ерунду дня два. Конечно, не с утра до вечера сидел, но всё равно времени ушло очень много. До сих пор не понимаю: не то я плохо искал, не то это всё настолько примитивно, что и писать стыдно – одни вопросы. В любом случае никакого исчерпывающего руководства я не нашёл. При всей простоте задачи всё время возникают какие-то подводные камни. Непонятно как настроить POEdit без специальных знаний, как называть .po и .mo файлы, где их размещать и ещё много чего.
И напоследок…
Если совсем ничего не получается (или не совсем, а только что-то), то обращайтесь за помощью ко мне.
Спасибо, пригодилась информация, изложенная в статье!
На здоровье, Алина!
Доброго времени суток! Я в файле ru_RU.po изменил падежи месяцев, но после обновления вордпресса все переводы пропали. Что можно сделать?
Здравствуйте! А где Вы их разместили? Исправленные файлы надо разместить в дочерней теме. Как её создать пишу тут: https://dvascheta.ru/vsyo-o-wordpress/kak-izmenit-shablon-temu-wordpress-na-primere-twenty-eleven.html Если Вы просто отредактируете существующие файлы в установленной теме, то после её обновления эти правки, конечно, могут потеряться.
Вот сейчас изменил в другой локализации (той что отображается) строку, а она все равно по старому отображается без изменений….(((
В таких общих категориях что-то более определённое сказать не могу. Если хотите, продолжим по почте/Скайпу.
Здравствуйте. Перевожу тему. Проблема в том что не весь перевод подхватывается. Часть переводится часть нет. Подскажите решение.
Здравствуйте, Иван! Навскидку: вероятная причина — неполный или неактуальный .po файл. Такое может быть, если, скажем, плагин обновили, а про этот файл забыли (если используете готовый). Попробуйте обновить его. Если генерировали его сами, то может быть как было у меня (смотрите дополнение от 13.10.2013), то есть, может быть, что надо расширить перечень ключевых слов исходных файлов.
Да нет тема куплена, я его не генерировал, скорее всего косяк в сроках. Не соответствуют. К примеру, один языковой перевод нормально в одних местах отображается, а другой в других. Не знаю как это все в один файл людский собрать.
Ну, тогда обновите его в первую очередь. Он же легко строится по исходникам. Берёте каталог с исходными кодами темы, и натравливаете программу на этот каталог.
Если не поможет, дальнейшие исследования более сложные: смотрите место, которое не переводится, ищете его в исходниках. Если там идёт просто вывод, то, оно переводиться и не будет. Если сделано по уму, через функции __() (два подчёркивания), то тогда проблема решаема, надо построить просто .po файл правильно.
Переводил на днях темку под заказ. Там было весело.
Pot файл там есть. но….. пустой. Только копирайты
Есть файлы английской локали, пустой pot и все.
Пришлось продублировать английские файлы. Открываю редактор… Переводим на англ (США)
Закрываю. Открываю заново. Он при запуске предлагает выбрать язык — ставлю русский.
Открываю файл — перводим на русский. Что изменилось — не понял но файлы перевел — заказчик доволен.
Да, бывает и такое. Почему было не сгенерировать .po или .pot файлы по новой по исходникам? Кстати, POEdit существенно шагнул вперёд в этой теме. Надо написать про него ещё, но руки не доходят.
Если Вы заинтересованы в инструменте, который обеспечивает быстрый и эффективный перевод тем и плагинов WordPress, я рекомендую Вам использовать этот инструмент на базе web:http://poeditor.com/ Особенностью данного инструмента является наличие плагина, который Вы можете использовать для интеграции его API в Ваш WordPress. Это позволяет Вам сэкономить значительное время на процессе организации файлов. Пожалуйста, пройдите по этой ссылке: http://wordpress.org/extend/plugins/poeditor/
Похоже на роботизированный комментарий… Я же POEdit и использовал… А плагин в данном случае ставить не рекомендую, потому что лишние плагины – это всегда плохо, а поскольку задача перевода разовая, то я обхожусь отдельной программкой.
> nplurals=2; plural=n != 1; – не спрашивайте почему
Во-первых, см. документацию на gettext — там написано.
Во-вторых, для русского языка нужна другая формула:
nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100=20) ? 1 : 2;
Спасибо! Голова просто пухнет во всём разобраться. У меня больше проблем возникло с ключевыми словами. Для ряда плагинов пришлось список расширить.