Рефакторинг темы WordPress: что ревьюить в pull request
Переименованный шаблон, новый ID сайдбара или другой текстовый домен не ломают вёрстку, но молча роняют страницы, виджеты и переводы. Что проверять при рефакторинге темы WordPress 6.x до выката.

Типичный сценарий: при рефакторинге файл page-contacts.php переименовали в page-contact.php. Диф чистый, вёрстка не тронута. На проде страница /contacts/ молча стала обычной page.php: без карты и формы. Ни ошибки, ни строки в логе. WordPress просто выбрал другой шаблон по иерархии. Рефакторинг темы ломает не то, что видно в диффе, а связи между кодом, базой и плагинами. Ниже: что искать на ревью и как формулировать замечания, чтобы их не приходилось объяснять дважды.
Что ломается без единой ошибки
Материал написан для WordPress 6.x и PHP 8.x и касается классической темы на PHP-шаблонах. Блочные темы затронем в граничных случаях, а перенос с классической на блочную — отдельная тема.
У темы есть публичные имена. Остальные части системы обращаются к ним по строке, а не через вызов функции. Строку переименовали, и связь рвётся без предупреждения. Вот что ревьюер ищет в диффе в первую очередь:
- Файлы шаблонов. Страница с выбранным в админке шаблоном хранит имя файла в метаполе. Файл удалили или переименовали, и WordPress берёт шаблон по умолчанию. Вернули имя, и привязка обычно оживает: метаполе осталось.
- ID сайдбаров. Новый
idвregister_sidebar, и виджеты прежней области уходят в «Неиспользуемые виджеты». - Ключи локаций меню. Сменили ключ в
register_nav_menus, и меню отвязано от места. Шапка пустая. - Имя папки темы. Настройки кастомайзера лежат в опции
theme_mods_с именем папки. Переименовали папку, и логотип, цвета и привязки меню выглядят сброшенными. - Шорткоды, типы записей и таксономии в теме. Убрали из темы, и в текстах остаётся сырой
[shortcode], а записи кастомного типа пропадают с сайта. Контент в базе цел, просто невидим. Если меняли слаг типа, нужно обновить постоянные ссылки. - Размеры изображений и текстовый домен. Новое имя в
add_image_sizeне создаёт миниатюры для старых файлов, пока их не пересоздать. Другой text domain в__()возвращает интерфейс на английский.
Хороший рефакторинг темы не меняет ни одного публичного имени. Если меняет, это уже миграция, и ей нужен отдельный план отката.
Порядок ревью
Читать диф сверху вниз мало. Работайте от рисков:
- Выпишите из дифа все переименования и удаления: файлы шаблонов, ID, ключи, handle скриптов, text domain. Это список рисков, а не вёрстка.
- По каждому пункту найдите, кто на него ссылается: сама тема, дочерняя тема, mu-плагины, плагины. То, что хранится в базе, проверяется только на стейдже с копией боевой базы.
- Откройте на стейдже по странице каждого типа: главная, запись, страница с кастомным шаблоном, архив рубрики, поиск, 404, страница с формой.
- Зайдите в админку: меню, виджеты, кастомайзер, список записей кастомных типов.
- Включите
WP_DEBUGс записью в лог и пройдите те же страницы. Ищите предупреждения, а не только фатальные ошибки. - Прогоните PHPCS с правилами WordPress Coding Standards, чтобы механические замечания не отнимали время у людей.
Безопасность: формулировки замечаний
При рефакторинге вывод часто переезжает в новые части шаблона, и экранирование теряется по дороге. Проверяйте каждый echo в перенесённом коде. Конкретные замечания звучат так:
- Значение из пользовательского поля выводится в атрибут без
esc_attr. Любой, кто может править поля записи, получает XSS на странице. - Ссылка прогнана через
esc_html. Дляhrefнуженesc_url, иначе схемаjavascript:проходит. - AJAX-обработчик в
functions.phpне проверяет nonce и права черезcurrent_user_can. Запрос может отправить любой посетитель. - SQL собран конкатенацией. Используйте
$wpdb->prepareилиWP_Query.
Производительность: что мерить
Готовых цифр здесь не будет: они зависят от хостинга, объёма данных и набора плагинов. Мерьте сами, на стейдже с копией боевой базы, с одинаково выключенным кешем, по три прогона на страницу, берите медиану. Для каждого типа страницы зафиксируйте до и после: число запросов к БД, суммарное время запросов, число дубликатов, число подключённых CSS и JS, TTFB, вес HTML. Для запросов удобен плагин Query Monitor.
| Область | Чем проверить | Красный флаг | Как сформулировать |
|---|---|---|---|
| Выборки | Query Monitor, запросы по компонентам | WP_Query внутри цикла; posts_per_page со значением -1 | Выборка без лимита отдаст все записи сразу. Нужен лимит или пагинация, а без пагинации ещё и no_found_rows. |
| Скрипты и стили | Query Monitor, вкладка ресурсов | Подключение без условий на всех страницах; ручной тег script в header.php | Слайдер нужен только на главной. Подключите условно через wp_enqueue_script. |
| Версии ресурсов | Исходный код страницы | Версия не указана или зашита вручную | Браузер держит старый CSS после выката. Берите версию из темы или время изменения файла. |
Где подход ломается
Дочерняя тема
Дочерняя тема переопределяет шаблоны родителя по имени файла и может вызывать его функции. Переименовали функцию в родительском functions.php, получили фатальную ошибку на всех страницах. Пути тоже путаются: get_template_directory указывает на родителя, get_stylesheet_directory на дочернюю тему. Замечание: файл, который должна переопределять дочерняя тема, подключайте через get_template_part, он ищет сначала в дочерней теме.
Хуки, на которые рассчитывают плагины
Потеряли вызов wp_footer() в footer.php при переносе, и пропали скрипты плагинов и панель администратора. Та же история с wp_head(), body_class() и wp_body_open(). Проверяйте, что они остались на месте во всех шаблонах каркаса.
Старый код и PHP 8.x
Рефакторинг старой темы вскрывает устаревшие конструкции. create_function удалена в PHP 8.0, передача null во встроенные функции объявлена устаревшей в 8.1, динамические свойства в 8.2. Предупреждения видны только при включённом логе, поэтому он нужен на стейдже.
Блочные темы
Иерархия шаблонов работает по тем же правилам, но шаблоны, изменённые в Редакторе сайта, хранятся в базе и перекрывают файлы темы. Правка файла в репозитории их не затронет. Сверяйте и файлы, и то, что видно в редакторе.
Что делать дальше
- Подключите PHPCS с WordPress Coding Standards в CI, чтобы ревьюер видел только содержательные замечания.
- Заведите в репозитории файл со списком публичных имён темы: шаблоны, ID сайдбаров, ключи меню, text domain. Любой диф, который их трогает, требует отдельного одобрения.
- Сохраните замеры из раздела про производительность как базовую линию. Следующий рефакторинг сравнивайте с ней, а не с памятью.
- Добавьте в шаблон pull request чек-лист из шести шагов выше.
Экранирование на выводе (escaping) — преобразование значения в безопасную строку для конкретного контекста в момент вывода: esc_html для текста, esc_attr для атрибутов, esc_url для ссылок. Очистка при сохранении его не заменяет.
Локализатор видео: Перевод и озвучка видео на другой язык с укладкой в исходный тайминг. Глоссарий терминов, отметки проблемных реплик.
Спросить за 250 ₽Источники: WordPress Theme Handbook: Template Hierarchy, WordPress APIs: Escaping Data
Частые вопросы
А если у меня другая версия WordPress или PHP?
Страницы слетели на обычный шаблон после выката. Как откатить?
Чем мерить производительность до и после рефакторинга?
Что ломается в проде, хотя на стейдже всё работало?
Нужно ли ревьюить блочную тему иначе?
Что делать с темой, у которой есть дочерняя тема?
Материал носит информационный характер и подготовлен редакцией «Агентуры». Он не является офертой, рекламой или индивидуальной консультацией. Упомянутые продукты, компании и торговые знаки принадлежат их правообладателям. Перед принятием решений, влекущих юридические или финансовые последствия, обратитесь к профильному специалисту.