СоНоты

Руссификация тем WordPress’а

Начав поближе разбираться с WordPress'ом сразу столкнулся с необходимостью руссификации его тем. Применение решения "в лоб" связанное с прямым переводом отображаемых слов в исходниках мне как-то не импонирует. А столкнувшись с приятной возможностью локализации в теме Binary Blue я понял, что это то что надо. Немного поигравшись с новыми возможностями, я перешёл к другой теме и попробовал таким же образом руссифицировать и её. Не тут-то было!

Вначале о самом методе локализации. Его идея проста. Сперва создаем «базу» оригинальных слов/фраз и соответствующих им переводов, затем, перед отображением слова/фразы вызываем некую функцию, которая проверяет наличие в базе такой связки и если есть перевод, то на экран выводится именно перевод. Ну, а если нет, то оригинальное слово. Причём, таких функций может быть несколько.
WordPress использует для реализации собственной локализации именно такой метод и его код базируется на GNU gettext'е. Если вас интересуют технические подробности, то с ними лучше ознакомится на страничке с документацией на gettext. Вы должны знать, что в реализации всё несколько сложнее чем я описал. Т.е. я дал самую общую схему. Интересуют нюансы? Вы уже знаете где их найти. Меня, как, наверное и вас, интересует практическая сторона дела. Поэтому и перейдём к практике.

На этой странице в разделе "Translation Tools" выбираете удобный для вас редактор, в исходниках WordPress'а (wp-includes/languages) находите файл *.po, подсовываете его редактору и начинаете переводить. В итоге вашей работы вы должны получить файл с таким же именем, но расширением mo. Вот его кладёте туда же где взяли исходный файл, обновляете страничку и наслаждаетесь родными буквами. Кайф! Как всё просто! Но вы правильно сейчас подумали "а в чём же вас обманывают?" Не всё так просто.

Во-первых, вы редактору должны указать, что в итоге вас интересует кодировка UTF-8. Во-вторых, вы должны точно знать как назвать выходной файл, т.к. от имени файла зависит почти всё. Помните: как вы судно назовёте, так оно и поплывёт? Другое дело, что в нашем случае выбор нужных имён ограничен одним именем - ru_RU. И всё. Но если вы переводите и на другие языки, то обязательно почитатйте документацию на этой странице, особенно приложения "A. Language Codes" и "B. Country Codes". В общем, предположим, что у вас есть файл en_EN.po. Вы просто переименуете/копируете его в ru_RU и редактируете уже новый файл.

Небольшое отступление. Я всё время говорю про файлы с расширениями mo и po. Так вот файлы po, это обычные текстовые файлы и вы може посмотреть что и как в них. mo файлы, это уже скомпилированные базы и они имеют двоичный формат.

Но, наверняка, WordPress у вас взят с русского сайта и у вас уже отображается русский текст и в указанной мной директории уже лежит файл ru_RU.mo. Так что остаётся только руссифицировать понравившиеся темы. Нет, конечно, остаются вопросы правильного склонения падежов русских языка и выборов правильного суффикса и окончаниев. Но это уже нюансы и, при должном кропотливом отношении, это можно решить тем или иным способом.

Наконец-то возвращаемся к локализации тем. Долго подходили, но всё же дошли. Так вот. Если тема уже поддерживает описанную выше технологию, то вы в корневом каталоге темы найдёте файл *.po. Что с ним делать я уже рассказал. Полученный в итоге всех манипуляций ru_RU.mo копируете в этот же каталог и начинаете заниматься подчисткой огрехов перевода.

А если в каталоге нет ничего отдаленно напоминающего описанные мной файлы? И в документации на тему нет ни слова про локализацию? Это чуть хуже, но "мы не привыкли отступать" © киножурнал "хочу всё знать".

Ещё одно отступление. Причиной побудившей меня написать эту заметку стало то, что я не смог не смог найти в Инете способа как сделать то, что описано ниже. Даже на сайте WordPress'а. По-видимому плохо искал. Ибо других причин я не вижу. Ещё раз, прямолинейный перевод исходных текстов лично я считаю идеологически не верным. Но это вопрос личных пристрастий и у вас может быть совсем другое мнение.

Вариант 1. Смотрим в любой файл в корневой директории темы, например, в index.php. Если в нём вы видите строчки типа _e('read more...', 'ddd.en') или __('read more...', 'eee.de'), то не всё ещё потеряно. Эти строки говорят о том, что автор темы всё же включил код позволяющий её локализовать. Внимание! В тексте могут быть строчки типа _e('read more...') - это не то! Это кусочки локализации самого WordPress'а и нам они не помогут. Предположим что указанные мной строки всё же есть. В этом случае, в редакторе помогающем нам в переводе настраиваем ключевые слова на _e и __. После этого натравливаем (синхронизируем) его на директорию с исходниками темы. После синхронизации вы должны увидеть все выбранные из функций _e и __ слова и фразы для перевода. Радуемся, переводим, сохраняем с нужным нам именем (ru_RU), ну и так далее.

Перед рассмотрением второго варианта немного о функциях _e и __. Это те самые функции о которых я говорил в самом начале - функции обращающиеся к базе, осуществляющие в ней поиск и возвращающие либо перевод, либо оригинальное слово/фразу. Разница между ними в том что _e отображает перевод аналогично print, echo и пр. А __ - возращает перевод. Вот пример использования:

_e('English');
$m = __(USA);
echo "$m";

Вариант 2. В исходниках темы не нашлось функций указывающих на использование автором локализации. Что ж, в этом случае, набираемся терпения и приступаем к кропотливому труду по включению всех иностранных слов в означенные выше функции. Конечно, при этом у вас должны быть хотя бы начальные познания в программировании, HTML'е и языке PHP. Вы должны понимать в каком месте надо использовать _e, а в каком __. Вы должны знать как изменить HTML строку с переводимой фразой на строку содержащию вызов этих функций. Как изменить код php на использование этих функций.

Кстати, не надо заранее сильно пугаться предстоящей работы. Если тема не сильно навороченная, то вам прийдётся не так уж и долго истирать клавиши. Достаточно сказать, что в очень продвинутой теме Binary Blue мне пришлось переводить 143 фразы, а значит, если бы я сам локализовал эту тему, мне пришлось бы "внедрить" эти функции 143 раза. Поверте, это не так уж и много. А в более простой теме Arzel_XT2 мне реально пришлось проделать операцию по "внедрению" всего-то 46 раз.

Считаем, что все препятствия успешно преодолены, и соотвествующие фразы вписанны в нужные функции. Кстати, если всё сделано правильно, то изменённый вами код не должен повлиять на работу темы! Ни коим образом! Т.е. внешне всё должно остаться так как и было! Такое поведение говорит о том, что вы всё сделали правильно. Теперь, как и в первом варианте, настраиваем редактор на ключевые слова _e и __ и... Ох, не буду писать, прочитайте выше, что делать дальше. Я подожду.

Сделали? Получился файлик ru_RU.mo? Положили его в корневой каталог темы? И даже обновили страничку? И что? Ни чего? Нет русского текста в тех местах где он должен был быть после всех этих манипуляций? Вот! Вот и я был озадачен точно так же. На этой самой стадии я и попал в ситуацию описанную мной в ещё одном отступлении. Вот как раз, как сказать WordPress'у о том что у меня тут лежит руссификация и я переработал код, я и не нашёл в Инете. Пришлось рыть исходники. Не буду описывать процесс рытья - он конечно, интересный, но не о нём речь.

В директории wp-includes лежит файлик wp-l10n.php. Вот в нём и оказались все ответы.

Настало время поговорить и о втором аргументе ('ddd.en') функций _e и __. Этот аргумент может быть любой строкой. Вы можете назвать его, например, 'mysite.ru' или ещё как - не важно. Важно, чтобы он фигурировал в качестве параметра одной (или чуть больше) важной функции которую вы разместите в одном из файлов локализуемой темы. Это будет один из файлов который обязательно будет вызван при каждом обращении к страницам вашего блога. В моём случае это был index.php. В локализуемой вами теме это может быть и другой файл. Хотя, похоже, есть один признак по которому вы можете отыскать нужное вам место. Это наличие в самых первых строках файла следующего кода:

require('./wp-config.php');

Причём, вместо require может быть include. Главное чтоб присутствовал wp-config.php. Вот перед или после этой строки и надо вставить следующую функцию:

load_theme_textdomain('mysite.ru');

Естественно, все ваши функции _e и __ должны в качестве второго аргумента содержать то что вы вписываете аргументом в этой строке. Вот теперь, действительно всё. Локализация просто обязана заработать.

В файле wp-includes/wp-l10n.php есть ещё ряд функций типа load_*_textdomain. Но вряд ли вам прийдётся их использовать. Хотя я не вижу ни каких препятствия к их использованию. Конечно, по необходимости.

Надеюсь не сильно утомил? 🙂

Тогда ещё довесочек. Так, просто для информации. Вот заголовок моего po файла:


msgid ""
msgstr ""
"Project-Id-Version: WP My Theme\n"
"POT-Creation-Date: \n"
"PO-Revision-Date: 2006-02-04 18:05+0300\n"
"Last-Translator: Michael Babakov\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Poedit-Language: Russian\n"
"X-Poedit-Country: RUSSIAN FEDERATION\n"
"X-Poedit-SourceCharset: utf-8\n"
"X-Poedit-KeywordsList: __;_e\n"
"X-Poedit-Basepath: .\n"
"X-Poedit-SearchPath-0: .\n"