Для початку потрібно визначити декілька фактів.

1. Ти можеш відразу створити двійко файлів із розширеннями .mo і .po, які міститимуть переклади з англійської на твою рідну мову. З них потім можна буде створити інші переклади.

2. Ти можеш нічого не перекладати, а просто, пишучи тему, залишати спеціальні записи, які допоможуть знайти всі рядки для перекладу. У WordPress за переклади відповідають наступні функції:

  • __()
  • _e()
  • _n()
  • _n_noop()
  • _x()
  • _ex()
  • _nx()

Деякі з цих функцій навіть мають розширені версії із підтримкою очищення даних:

  • esc_attr__()
  • esc_attr_e()
  • esc_attr_x()
  • esc_html__()
  • esc_html_e()
  • esc_html_x()

Отже, припустімо, у нашому коді є текст «Hello World!», який потрібно перекласти на «Привіт, світ!». Для цього використовуємо наступний приклад:

echo __( 'Hello World!', 'text_domain' ); 

Другий аргумент функції, 'text_domain', — це назва текстового домену перекладу. Він може бути довільним, але важливо, щоб збігався з відповідним параметром під час підключення файлів перекладу. Зазвичай цей параметр відповідає назві директорії теми або плаґіна. Він є необов’язковим: якщо його не вказати, для перекладу будуть використовуватися стандартні мовні файли, які застосовуються для локалізації ядра WordPress та адміністративної панелі. Однак зрозуміло, що в стандартних файлах може не бути перекладів тих рядків, які є у твоїй темі або плаґіні.

Приклад із використанням функції _e() виглядає так:

_e( 'Hello World!', 'text_domain' ); 

Тож, якщо потрібно вивести перекладений рядок, використовуємо функцію _e(). Якщо ж рядок необхідно записати у змінну або використовувати як аргумент іншої функції, застосовуємо __().

Крім того, якщо виведений код потребує очищення, то твій рядок виглядатиме так:

<h1><?php esc_html_e( 'Hello World!', 'text_domain' ); ?></h1> 

Таким чином, підготовлюємо свою тему або плаґін до перекладу та переходимо до наступного кроку.

3. Також ти можеш проявити люб'язність та турботу про користувачів твого шаблону і залишити для них файл із готовими рядками для перекладу у форматі .pot. Розглянемо цей випадок детальніше просто зараз.

Встановлення WP-CLI

Для початку підготуємо систему, встановивши консольну програму WP-CLI.

Наголошую – дана програма потребує UNIX-подібне середовище (OS X, Linux, FreeBSD, Cygwin). Підтримка в середовищі Windows обмежена.

WP-CLI (WP Command Line Interface) – це інтерфейс командного рядка для WordPress. Він дозволяє оновлювати плагіни, налаштовувати мультисайтові встановлення та багато іншого, без використання браузера.

В нашому випадку WP-CLI служитиме для генерування вищезгаданого файлу POT для перекладів. Але якщо ти постійно працюєш із WordPress, раджу познайомитися з цією програмою поближче 😉

Отож, звантажуємо файл wp-cli.phar:

wget https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar

Переконуємося, що звантажений файл адекватно працює:

php wp-cli.phar --info

Надаємо файлу права на виконання та переміщуємо в будь-яке місце, оголошене у змінній PATH, наприклад, отак:

chmod +x wp-cli.phar
sudo mv wp-cli.phar /usr/local/bin/wp

Тепер ти можеш запустити програму в терміналі простою командою wp. Наприклад, ще раз протестувати роботу програми, взнавши інформацію про неї:

wp --info

Або оновити її:

wp cli update

Що далі?

А далі все просто. Пишеш собі шаблон і ні про що не думаєш, лише підставляєш потрібні для перекладу елементи через функцію esc_html__(). А вкінці в терміналі із теки з твоїм шаблоном вводиш наступну команду:

wp i18n make-pot . languages/mytheme.pot --domain=text_domain

Де крапка означає пошук значень у даній теці, а все, що після неї – шлях до файлу POT та його назва (назву зазвичай дають таку саму, як назва основної теки шаблона). Тобто фактично команда виглядає отак:

wp i18n make-pot [тека з шаблоном] [вихідний файл POT] --domain=[домен перекладу]

Що робити з файлом POT?

POT-файли найкраще відкривати безкоштовною програмою Poedit. Просто відкриваєш файл даною програмою, бачиш список фраз для перекладу, обираєш мову та підставляєш фрази обраною мовою. Потім просто зберігаєш файл, він автоматично збережеться, наприклад, у файл uk.po, а також (теж автоматично) скомпілює файл uk.mo, який, власне, й перекладатиме весь твій сайт:

Poedit

Якщо ти не генеруєш файлу POT

У такому випадку нам потрібно згенерувати рядки для перекладу із теки теми чи плаґіна. Для цього відкриваємо ту ж програму Poedit, у ній клацаємо по пункту Файл -> Новий:

Створюємо новий переклад в Poedit

Відразу обираємо потрібну мову перекладу:

Обираємо мову перекладу в Poedit

У вікні, що з'явилося, обираємо пункт "Видобути з початкового коду":

Обираємо спосіб перекладу в Poedit

Заповнюємо дані щодо перекладу, тут найосновніше – вказати правиьне кодування, решта пунктів не надто важливі:

Заповнюємо інформацію про переклад у Poedit

Далі треба зберегти файл перекладу, інакше Poedit відмовиться продовжувати роботу.

Щоб файли перекладу правильно працювали, необхідно правильно розташувати та назвати їх. Для цього створюємо у теці своєї теми чи плаґіну нову теку languages, далі формуємо правильні назви файлів:

  1. Для плаґінів – [домен перекладу]-[мова], наприклад у нашому випадку – text_domain-uk.po та text_domain-uk.mo.
  2. Для тем – вистачить тільки мови, без домена перекладу, тобто uk.po та uk.mo. Взагалі "по феншую" мало б бути uk_UA.po, але з такими назвами в мене чомусь не працює, а з короткими uk.po – без проблем.

Після збереження можливо доведеться також ще раз клацнути по пункту "Видобути з початкового коду", після цього переходимо на вкладку "Шлях до джерел" та обираємо теку із своєю темою чи плагіном:

Зберігаємо переклад та обираємо шлях до файлів у Poedit

Наступним кроком у вкладці "Ключові слова початкових файлів" вносимо усі функції, які ми використовували для позначення перекладів. Це може бути одна-дві функції, а може бути весь отакий список, залежно від розміру проєкту:

Вносимо у Poedit функції, що відповідають за переклад

Для зручності ось повний список функцій перекладу WordPress у вигляді, в якому їх потрібно вносити в Poedit:

__
_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

Хочу наголосити, що якщо ти перекладаєш якийсь готовий проєкт навіть із готового POT-файлу, тобі, можливо, доведеться все одно налаштувати даний етап, оскільки для різних мов існують різні форми множини, а також різні випадки омонімів. Щоб зрозуміти, про що йде мова, варто почитати окремо про кожну із функцій перекладу (посилання у списках функцій на початку даної статті). У двох словах поясню тут:

  • Функція __() приймає лише один обов'язковий параметр для перекладу, а другим аргументом є текстовий домен. Усі функції перекладу, які мають тільки два такі параметри, в Poedit зазначаються просто у вигляді їхніх назв.
  • Функція множини _n() має закінчення :1,2. Це означає, що перший та другий параметри цієї функції підлягають перекладу, оскільки вони відповідають за однину та множину.
  • Функція _x() має закінчення :1,2c. Це вказує, що перший параметр функції перекладається, а другий є контекстом для перекладу, що допомагає уникнути неоднозначності.
  • Функція _nx() поєднує можливості функцій _n() та _x(). Її закінчення виглядає як :4c,1,2, що означає:
    • четвертий параметр використовується як контекст перекладу,
    • перший і другий параметри перекладаються (вони відповідають за однину та множину).

Таким чином, кожна з цих функцій має свої особливості, які враховуються при роботі з перекладами у Poedit.

Що далі?

Далі нам залишається опрацювати кожен рядок:

Перекладаємо рядки в Poedit.

Зберегти зміни та скомпілювати файл .mo :

Компілюємо файли перекладу в Poedit.

Підключення мовних файлів у плаґіні чи шаблоні WordPress

Якщо ми готуємо тему до перекладу, відкриваємо її файл functions.php і додаємо наступний код:

add_action('after_setup_theme', 'load_new_theme_textdomain');
function load_new_theme_textdomain(){
	load_theme_textdomain( 'text_domain', get_template_directory() . '/languages' );
}

Перший аргумент функції load_theme_textdomain() — це текстовий домен, який також використовується у функціях __() та _e(). Другий аргумент визначає шлях до папки з мовними файлами. Використовується функція get_template_directory() для отримання шляху до папки поточної теми.

Якщо ж ми перекладаємо плагін, потрібно відкрити головний файл плагіна і додати такий код:

add_action( 'plugins_loaded', 'load_new_plugin_textdomain' );
function load_new_plugin_textdomain() {
	load_plugin_textdomain( 'text_domain', false, dirname( plugin_basename( __FILE__ ) ) . '/languages/' ); 
}

Для плагінів використовується інша функція — load_plugin_textdomain(). Її основна відмінність полягає у другому аргументі, який у нових версіях WordPress завжди повинен дорівнювати false. Для визначення шляху до папки плагіна застосовується функція plugin_basename().

Таким чином, як для тем, так і для плагінів, структура налаштування перекладу базується на правильному визначенні текстового домену та шляху до мовних файлів.

Часті помилки

При підготовці локалізації теми чи плаґіна WordPress дуже легко наробити помилок, які потім важкувато відловити і виправити. Для цього залишаю кілька порад.

Помилка 1. Відсутність текстового домену у функціях перекладу

Неправильно писати:

echo __( 'Hello World!' );

У цьому випадку WordPress не знає, до якого домену належить цей рядок, тому переклад може не працювати. Правильно отак:

echo __( 'Hello World!', 'text_domain' );

Помилка 2. Використання змінних у функціях перекладу

Неправильно писати:

$result = __( $string, 'text_domain' );  
$result = __( "На складі залишилось $number одиниць товару", 'text_domain' );  
$result = __( 'На складі залишилось 5 одиниць товару', $domain );  
$result = __( 'На складі залишилось 5 одиниць товару', PLUGIN_DOMAIN );

Правильно отак:

$result = __( 'На складі залишилось 5 одиниць товару', 'text_domain' );

Помилка 3. Перекладай цілі фрази, а не окремі рядки

Неправильно писати:

$result = __( 'На складі залишилось ', 'text_domain' ) . $number . __( ' одиниць товару', 'text_domain' );

Правильно отак:

$result = sprintf( __( 'На складі залишилось %d одиниць товару', 'text_domain' ), $number );

Помилка 4. Уникай HTML у функціях перекладу, якщо це можливо

Не давай перекладачеві змоги змінювати HTML-розмітку теми. Всі HTML-теги краще винести за межі перекладених рядків, де тільки це можливо.

Неправильно писати:

$result = sprintf( __( '<h3>На складі залишилось %d одиниць товару</h3>', 'truemisha' ), $number );

Правильно отак:

$result = '<h3>' . sprintf( __( 'На складі залишилось %d одиниць товару', 'text_domain' ), $number ) . '</h3>';

Висновок

Коли готуєш тему чи плаґін WordPress до перекладу, важливо дотримуватись певних правил, щоб забезпечити зручність для перекладачів і коректність роботи локалізації. Використовуй лише статичні рядки у функціях перекладу, правильно структуруй фрази для підтримки числових форм та завжди відокремлюй HTML від тексту, який потрібно перекласти.

Дотримуючись цих простих рекомендацій, ти зможеш створювати якісний і локалізований продукт, яким легко користуватимуться люди з різних країн. Не забувай, що коректна локалізація – це не лише про функціональність, а й про комфорт і довіру користувачів.