Работа с i18n в WordPress чаще всего ломается в одном месте — когда в строке перевода появляется HTML. Сначала «вроде работает», потом подключается другой язык — и разметка начинает вести себя непредсказуемо. Разберёмся, как делать правильно.
Проблема
Разработчик пишет:
<h2><b><?php _e('<b>Calculator</b> storage cost', 'storage-calculator'); ?></b></h2>
Что происходит:
- HTML внутри строки перевода
- Дублирование <b>
- Переводчик может удалить или изменить тег
- Нарушается WordPress i18n best practice
Работает? Да.
Правильно? Нет.
HTML должен находиться в шаблоне, текст — в переводе.
Вариант 1 — простой и безопасный
Если порядок слов не критичен:
<h2>
<b><?php esc_html_e('Calculator', 'storage-calculator'); ?></b>
<?php esc_html_e('storage cost', 'storage-calculator'); ?>
</h2>
— нет HTML в переводах
— невозможно сломать разметку
— максимально предсказуемо
Минус: в некоторых языках нельзя поменять порядок слов.
Вариант 2 — универсальный и гибкий (через printf)
Если нужен один перевод и возможность менять порядок слов:
<h2>
<?php
printf(
__('%1$sCalculator%2$s storage cost', 'storage-calculator'),
'<b>',
'</b>'
);
?>
</h2>
В .pot попадёт строка:
msgid "%1$sCalculator%2$s storage cost"
msgstr ""
В ru.po:
msgid "%1$sCalculator%2$s storage cost"
msgstr "%1$sКалькулятор%2$s стоимости хранения"
WordPress не «понимает» тег <b>.
printf просто подставляет строки на их место.
Как это работает технически
__()возвращает переведённую строкуprintf()заменяет плейсхолдеры на <b> и </b>- Формируется корректный HTML
Итоговый результат:
<b>Калькулятор</b> стоимости хранения
Никакой магии. Только позиционная подстановка аргументов.
Дополнительная защита
Если проект крупный и есть риск, что в перевод добавят лишний HTML:
<h2>
<?php
printf(
wp_kses_post(__('%1$sCalculator%2$s storage cost', 'storage-calculator')),
'<b>',
'</b>'
);
?>
</h2>
Чего делать не стоит
<?php _e('<b>Calculator</b> storage cost', 'storage-calculator'); ?>
- HTML внутри переводов
- Высокий риск поломки вложенности
- Невозможно контролировать структуру разметки
- Проблемы масштабирования проекта
✔ Разделять HTML и текст — базовое правило
✔ Для гибкости использовать printf с плейсхолдерами
✔ Не хранить HTML в переводах
Так код остаётся предсказуемым, безопасным и соответствующим WordPress i18n best practices.