Глубокая разработка тем, шаблонов и плагинов для WordPress

Курс охватывает профессиональную разработку и поддержку тем и плагинов для WordPress: от архитектуры, хуков и шаблонов до безопасности, производительности и публикации. Упор на практические навыки, соответствие стандартам WordPress и работу с современным стеком инструментов.

1. Архитектура WordPress: ядро, жизненный цикл, структура проекта

Архитектура WordPress: ядро, жизненный цикл, структура проекта

WordPress часто воспринимают как набор шаблонов и плагинов, но для глубокой разработки важно видеть его как платформу с четким процессом загрузки (bootstrap), жизненным циклом запроса и контрактами расширения. Эта статья закладывает фундамент: как устроено ядро, какие шаги проходит любой запрос и где в проекте что лежит.

Из чего состоит WordPress

На практике WordPress можно представить как три слоя:

  • Ядро (core)
  • Контент и расширения (wp-content: плагины, темы, загрузки)
  • Конфигурация и окружение (wp-config.php, веб-сервер, PHP, база данных)
  • Ключевой принцип: ядро не модифицируют напрямую. Все изменения вносятся через плагины, темы и хуки.

    Ядро WordPress

    Ядро включает:

  • Загрузчик и файлы инициализации (bootstrap)
  • Подсистему хуков (actions и filters)
  • API: настройки, роли, посты, таксономии, мета-поля, REST, cron, rewrite, i18n
  • Подсистему запросов и шаблонов (WP_Query, Template Hierarchy)
  • Официальные справочники:

  • WordPress Developer Resources
  • Plugin Handbook
  • Theme Handbook
  • wp-content: где живет ваш код

    Вся расширяемость сосредоточена в wp-content:

  • wp-content/plugins — плагины
  • wp-content/mu-pluginsmust-use плагины (включены всегда)
  • wp-content/themes — темы
  • wp-content/uploads — медиафайлы (загрузки)
  • > Важно: все, что должно переживать смену темы, почти всегда должно быть плагином, а не кодом темы.

    Конфигурация и окружение

  • wp-config.php задает подключение к базе, соли, префикс таблиц, режим отладки и другие параметры.
  • См. документацию:

  • Editing wp-config.php
  • Структура проекта WordPress

    Типичная структура установки:

  • Корень сайта
  • - index.php - wp-admin/ - wp-includes/ - wp-content/ - wp-config.php

    !Дерево ключевых директорий WordPress и назначение wp-content

    Зачем разделение на wp-admin, wp-includes и wp-content

  • wp-admin — код админки (панель управления)
  • wp-includes — большая часть библиотек ядра
  • wp-content — ваш код и данные, которые не должны перетираться обновлением ядра
  • Это разделение обеспечивает обновляемость: ядро можно обновлять, не затрагивая плагины/темы.

    Плагины, MU-плагины и темы: что когда использовать

    | Механизм | Когда подходит | Когда не подходит | |---|---|---| | Плагин | Функциональность, независимая от дизайна: CPT, REST endpoints, интеграции, платежи, кеширование, шорткоды | Для логики, завязанной на конкретную тему и ее разметку | | MU-плагин (mu-plugins) | Код, который обязан быть включен всегда: обязательная безопасность, корпоративные политики, критичные интеграции | Когда нужен UI включения/выключения, настройки, зависимости от порядка загрузки обычных плагинов | | Тема | Представление: шаблоны, стили, компоненты интерфейса, небольшая glue-логика для вывода | Для бизнес-логики, которая должна пережить смену темы |

    О MU-плагинах:

  • Must Use Plugins
  • Жизненный цикл запроса: что происходит от HTTP до HTML

    Под жизненным циклом понимают последовательность шагов, через которые проходит WordPress при обработке запроса.

    Ниже — упрощенная, но практичная модель для разработчика тем и плагинов.

    !Последовательность загрузки WordPress и ключевые этапы для подключения кода

    Bootstrap: стартовые файлы загрузки

    В типичном запросе фронтенда цепочка начинается так:

  • index.php в корне
  • wp-blog-header.php
  • wp-load.php
  • wp-config.php
  • wp-settings.php
  • Точка, где в игру входят плагины и тема, фактически начинается в wp-settings.php: там инициализируются константы, подключаются файлы ядра, запускается система хуков и начинается загрузка расширений.

    Порядок подключения расширений (упрощенно)

    Важно понимать именно порядок, потому что он определяет, какие функции уже доступны и на какие хуки вы успеете подписаться.

  • Подключаются MU-плагины (wp-content/mu-plugins)
  • Подключаются обычные активированные плагины (wp-content/plugins)
  • Загружается активная тема и ее functions.php
  • Далее WordPress переходит к разбору запроса, выполнению WP_Query и выбору шаблона
  • Практическое следствие:

  • Если ваш код должен выполняться максимально рано и быть всегда активным, выбирайте MU-плагин.
  • Если код зависит от функций темы (или от того, что тема уже объявила поддержку чего-то), используйте хуки после загрузки темы.
  • Типы запросов в WordPress

    Один и тот же сайт может обслуживать разные сценарии, и в каждом жизненный цикл чуть отличается:

  • Фронтенд (публичные страницы)
  • Админка (/wp-admin/)
  • AJAX (обычно через admin-ajax.php)
  • REST API (/wp-json/...)
  • WP-Cron (псевдопланировщик)
  • WP-CLI (командная строка)
  • Почему это важно:

  • В админке есть свои хуки и экраны.
  • В REST вы обычно возвращаете JSON, а не HTML.
  • В AJAX вы часто хотите отключить лишний вывод и работать быстро.
  • Хуки (actions и filters): основной контракт расширения

    WordPress расширяется через систему хуков:

  • Action (действие) — событие, на которое вы подписываетесь, чтобы выполнить код. Action не предназначен для изменения передаваемого значения.
  • Filter (фильтр) — точка модификации значения. Filter получает значение, изменяет его и обязан вернуть результат.
  • Документация:

  • Actions
  • Filters
  • Пример фильтра (меняем содержимое поста):

    Пример action (подключаем скрипты):

    Ключевые этапы и популярные хуки жизненного цикла

    Ниже — ориентир, где обычно подключают разные типы логики:

  • Ранние этапы загрузки
  • - muplugins_loaded — MU-плагины загружены - plugins_loaded — загружены обычные плагины
  • Подключение темы
  • - after_setup_theme — тема объявляет поддержку возможностей, регистрирует меню и т.п.
  • Базовая инициализация
  • - init — один из главных хуков для регистрации: CPT, таксономии, rewrite, обработка форм - wp_loaded — WordPress загружен, можно опираться на большее количество подсистем
  • Разбор запроса и выбор шаблона
  • - parse_request, wp, template_redirect
  • Вывод страницы
  • - wp_head, wp_footer
  • Завершение
  • - shutdown

    Рекомендация по стилю: регистрируйте функциональность (CPT, таксономии) на init, а вещи, завязанные на тему (например, add_theme_support) — на after_setup_theme.

    Как WordPress выбирает шаблон: Template Hierarchy

    Когда WordPress понял, какой контент хотят, он подбирает PHP-файл шаблона в теме по правилам иерархии шаблонов.

    Примеры ситуаций:

  • Запрос одиночной записи (single)
  • Архив рубрики/таксономии
  • Страница (page)
  • Результаты поиска
  • 404
  • Документация:

  • Template Hierarchy
  • Практическая мысль для разработки: тема — это не один файл, а набор точек переопределения. Чем лучше вы понимаете иерархию, тем меньше условных операторов вам нужно внутри шаблонов.

    Точка входа данных: база и глобальные объекты

    WordPress хранит данные в базе (обычно MySQL/MariaDB), а доступ организует через API и ключевые объекты:

  • WP_Query — формирует основной запрос (что показать)
  • wpdb — низкоуровневый доступ к базе (использовать осторожно)
  • На уровне тем важнее всего понимать цикл (Loop): WordPress подготавливает набор постов, а шаблон выводит их.

    Практические правила архитектуры для разработчика

  • Не редактируйте файлы в wp-admin и wp-includes: обновление ядра перетрет изменения.
  • В теме держите представление, в плагине — функциональность.
  • Привязывайтесь к жизненному циклу через хуки, а не через хаотичный require.
  • Учитывайте контекст выполнения: фронтенд, админка, REST, AJAX, cron.
  • Документируйте точки интеграции: какие хуки используются и почему.
  • Что дальше по курсу

    Дальнейшие темы логично строятся на этой базе:

  • Подробная разработка плагинов: структура, загрузка, безопасность, настройки
  • Разработка тем: шаблоны, Template Hierarchy, подключение ассетов, блок-темы
  • Хуки и API WordPress как основной инструмент расширения
  • Производительность и архитектурные паттерны для крупных проектов
  • 2. Шаблонная система тем: hierarchy, template parts, блоки и Full Site Editing

    Шаблонная система тем: hierarchy, template parts, блоки и Full Site Editing

    Шаблонная система WordPress — это слой, который превращает результат запроса (какой контент показать) в итоговый вывод (как это выглядит). В предыдущей статье про архитектуру WordPress мы разобрали жизненный цикл запроса и то, что после WP_Query WordPress выбирает файл темы по правилам Template Hierarchy. Теперь углубимся в то, как именно устроены шаблоны в классических темах и в блочных темах (Full Site Editing), и как писать темы так, чтобы они были расширяемыми и поддерживаемыми.

    Ключевая идея: WordPress подбирает шаблон, а тема собирает страницу из частей

    Упрощенно процесс выглядит так:

  • WordPress определяет контекст запроса (например, одиночная запись, архив рубрики, страница, 404).
  • По правилам Template Hierarchy выбирается наиболее подходящий шаблон.
  • Внутри шаблона подключаются template parts (части шаблона) — шапка, подвал, сайдбар, карточки записей.
  • В блочной теме вместо PHP-шаблонов часто используются HTML-шаблоны и блоки, а настройка стилей и разметки переносится в Site Editor.
  • !Схема: от запроса до выбора шаблона и сборки страницы из частей

    Полезная документация:

  • Template Hierarchy
  • Theme Handbook
  • Block Themes
  • Template Hierarchy в классических темах

    Template Hierarchy — это набор правил, по которым WordPress выбирает PHP-файл шаблона в директории темы.

    Базовый набор шаблонов классической темы

    Минимально рабочая классическая тема обычно включает:

  • style.css
  • functions.php
  • index.php
  • Типовой расширенный набор:

  • front-page.php
  • home.php
  • single.php
  • page.php
  • archive.php
  • category.php
  • tag.php
  • taxonomy.php
  • author.php
  • search.php
  • 404.php
  • header.php
  • footer.php
  • sidebar.php
  • > index.phpпоследний резервный вариант: если WordPress не нашёл более специфичный шаблон, он использует index.php.

    Примеры выбора шаблона (как думать и как проектировать)

    #### Одиночная запись (single)

    WordPress проверяет варианты от более специфичных к менее специфичным. Например, для записи типа post могут рассматриваться (в общем смысле) такие уровни:

  • single-{post_type}.php
  • single.php
  • singular.php
  • index.php
  • Практический вывод: если вам нужно отдельное оформление для кастомного типа записей product, вы создаёте single-product.php, не трогая логику других одиночных страниц.

    #### Архив таксономии

    Для термина таксономии WordPress ищет файлы, начиная с максимально специфичных:

  • taxonomy-{taxonomy}-{term}.php
  • taxonomy-{taxonomy}.php
  • taxonomy.php
  • archive.php
  • index.php
  • Это удобно для проектов, где разным рубрикам/таксономиям нужна разная сетка, фильтры или верхние блоки.

    Где именно в жизненном цикле это происходит

    Из предыдущей статьи вам важно помнить связку:

  • На этапе init вы регистрируете сущности (например, custom post types и таксономии).
  • Затем WordPress парсит запрос и формирует главный WP_Query.
  • На template_redirect WordPress уже знает контекст и готов выбирать шаблон.
  • Именно поэтому регистрация типов/таксономий на init критична: иначе WordPress может не распознать контекст и выбрать не тот шаблон.

    Диагностика: как понять, какой шаблон используется

    Для диагностики есть несколько практик:

  • Временно вывести в шаблоне имя файла (например, комментарий в коде) и посмотреть результат.
  • Использовать фильтр template_include, чтобы логировать путь к шаблону.
  • Использовать плагин Query Monitor.
  • Пример (осторожно, только для разработки) — логирование выбранного шаблона:

    Справочник по хуку:

  • template_include
  • Template parts в классических темах: переиспользование и структура

    Template parts — это переиспользуемые куски шаблонов. В классических темах исторически использовали:

  • get_header()header.php
  • get_footer()footer.php
  • get_sidebar()sidebar.php
  • А также более гибкий механизм: get_template_part().

    Справочник:

  • get_template_part
  • Как проектировать template parts

    На практике лучше делать части шаблона по смыслу, а не по типу страницы. Например:

  • template-parts/content/content-card.php — карточка записи в списке
  • template-parts/content/content-single.php — контент одиночной записи
  • template-parts/site/site-header.php — шапка
  • template-parts/site/site-footer.php — подвал
  • Тогда archive.php и home.php могут переиспользовать одну и ту же карточку, а отличия держать в одном месте.

    Пример подключения карточки записи:

    WordPress будет искать:

  • template-parts/content/content-card.php
  • затем запасной вариант template-parts/content/content.php
  • Child theme и переопределение частей

    Дочерняя тема (child theme) может переопределять любые шаблоны и части, просто размещая файл с тем же относительным путём. Это один из базовых механизмов расширяемости тем без правки родительской темы.

    Документация:

  • Child Themes
  • Переход к блокам: что такое блочная тема и Full Site Editing

    Блочная тема (block theme) — это тема, которая использует блоки не только для контента, но и для структуры сайта: шапки, подвала, шаблонов страниц. Редактирование происходит через Site Editor (FSE).

    Важные компоненты блочной темы:

  • templates/*.html — шаблоны страниц
  • parts/*.html — части шаблонов (template parts)
  • theme.json — глобальные стили и настройки
  • patterns/*.php — блок-паттерны (заготовки блоков)
  • Документация:

  • Block Themes
  • Templates and template parts
  • theme.json
  • !Типичная структура блочной темы и назначение ключевых директорий

    Чем отличается Template Hierarchy в блочных темах

    Принцип выбора шаблона по контексту сохраняется, но:

  • Вместо single.php часто используется templates/single.html.
  • Разметка задаётся блоками, а данные (записи, заголовки, контент) выводятся блоками вроде Post Title, Post Content, Query Loop.
  • Многое настраивается в редакторе сайта, и изменения могут храниться в базе (как пользовательские варианты шаблонов).
  • При этом логика WordPress по выбору шаблона остаётся связанной с контекстом запроса; просто конечный файл шаблона теперь может быть HTML-шаблоном блочной темы.

    Template parts в FSE

    В блочных темах template parts живут в parts/.html и подключаются блоком Template Part* (например, шапка и подвал). Ключевой плюс — редактор может менять эти части визуально.

    Практический подход к проектированию parts:

  • Делайте части крупными и стабильными: header.html, footer.html, sidebar.html.
  • Мелкие переиспользуемые куски лучше оформлять как паттерны, а не как template parts.
  • Паттерны блоков (block patterns): переиспользуемые секции

    Паттерн — это заготовка из блоков, которую можно вставлять в контент или шаблон.

    Документация:

  • Block Patterns
  • Паттерны удобны для:

  • hero-секций
  • CTA-блоков
  • типовых сеток
  • секций «о компании», «преимущества»
  • С точки зрения архитектуры это аналог UI-компонентов, которые собираются из блоков.

    theme.json: глобальные стили и системные настройки

    theme.json — центральный файл, который задаёт:

  • глобальные стили (типографика, цвета, отступы)
  • доступность настроек в редакторе (что пользователю можно менять)
  • стили для конкретных блоков
  • Документация:

  • Global Settings and Styles (theme.json)
  • Практические принципы:

  • Описывайте дизайн-систему (палитра, шрифты, размеры) в theme.json, а не в разрозненных CSS.
  • Ограничивайте «опасные» настройки (например, произвольные цвета), если проекту важна консистентность.
  • Делайте стили блоков точечно: на уровне конкретных блоков вы избегаете каскадных конфликтов.
  • Как связать PHP и блок-тему: functions.php всё ещё важен

    Даже в FSE-подходе PHP может быть нужен для:

  • регистрации паттернов
  • регистрации пользовательских вариаций блоков
  • подключения дополнительных скриптов/стилей
  • регистрации меню, сайдбаров (если используется), поддержки возможностей
  • интеграции с плагинами и хуками
  • То есть тема становится сочетанием:

  • декларативного слоя (templates/parts/theme.json)
  • программного слоя (functions.php)
  • Практические сценарии и правильные точки расширения

    Сценарий: отдельный шаблон для кастомного типа записей

    Если плагин зарегистрировал тип movie, то в классической теме вы добавляете:

  • single-movie.php — одиночная страница
  • archive-movie.php — архив
  • В блочной теме вы добавляете:

  • templates/single-movie.html
  • templates/archive-movie.html
  • И дальше собираете страницу блоками (например, заголовок, мета-данные, контент, похожие записи).

    Сценарий: переиспользуемая карточка записи

    Классическая тема:

  • Вынести карточку в template-parts/content/content-card.php.
  • Блочная тема:

  • Использовать Query Loop и настроить структуру внутри (или оформить как паттерн, если нужна вставка в разные шаблоны).
  • Сценарий: что класть в тему, а что — в плагин

    Связь с архитектурными правилами из предыдущей статьи:

  • В тему: разметка, стили, шаблоны, parts, паттерны.
  • В плагин: сущности и бизнес-логика (CPT, таксономии, поля, REST, интеграции), потому что это должно переживать смену темы.
  • Частые ошибки при работе с иерархией и частями

  • Дублирование одного и того же HTML в нескольких шаблонах вместо выделения template parts или паттернов.
  • Перегрузка functions.php логикой, которая должна быть в плагине.
  • Смешивание задач: в шаблоне — сложные вычисления и доступ к базе напрямую вместо использования API и подготовки данных заранее.
  • Непонимание «последнего резерва»: index.php/templates/index.html должен существовать и быть безопасным дефолтом.
  • Что дальше по курсу

    Следующий логичный шаг после понимания иерархии и частей:

  • углубиться в разработку тем: подключение ассетов, настройка редактора, поддержка блоков
  • углубиться в разработку плагинов: регистрация сущностей (CPT/таксономии), мета-поля, REST, безопасность
  • практика архитектуры: как разделять ответственность между плагином и темой и где использовать хуки жизненного цикла
  • 3. PHP и WordPress APIs: хуки, WP_Query, CPT, таксономии, метаполя

    PHP и WordPress APIs: хуки, WP_Query, CPT, таксономии, метаполя

    Эта статья связывает предыдущие темы курса в единую практику.

  • Из статьи про архитектуру WordPress вам уже знаком жизненный цикл запроса и то, что расширение платформы происходит через хуки.
  • Из статьи про шаблонную систему вы знаете, что результат запроса превращается в HTML через Template Hierarchy и template parts (или через шаблоны/parts в блочных темах).
  • Теперь углубимся в ключевые API, на которых строится программирование тем и плагинов: хуки, WP_Query, кастомные типы записей (CPT), таксономии и метаполя. Это набор инструментов, который позволяет создавать структуру данных и управлять тем, как эти данные выбираются и отображаются.

    !Карта, где именно в процессе запроса размещать код: регистрация сущностей и изменение запроса

    Хуки WordPress: главный контракт расширения

    Хуки бывают двух типов.

  • Actions: запускают ваш код в ответ на событие.
  • Filters: позволяют изменить значение и вернуть результат.
  • Документация:

  • add_action
  • add_filter
  • Plugin API: Actions
  • Plugin API: Filters
  • Приоритет и количество аргументов

    Когда вы подписываетесь на хук, вы задаёте:

  • приоритет (чем меньше число, тем раньше выполнится колбэк)
  • сколько аргументов принять
  • Action: пример с регистрацией логики

    init часто используют для регистрации сущностей и правил.

    Почему именно init:

  • WordPress уже загрузил плагины
  • можно безопасно регистрировать типы записей, таксономии и rewrite-правила
  • Справочник по хуку:

  • init
  • Filter: пример изменения значения

    Фильтры обязаны вернуть значение.

    php add_action('pre_get_posts', function (query->is_main_query()) { return; }

    if (query->set('posts_per_page', 20); query->set('orderby', 'meta_value_num'); query->is_main_query().

  • Не меняйте запрос “везде”, иначе получите трудноотлаживаемые побочные эффекты.
  • Частые параметры WP_Query, которые используют в темах и плагинах

    | Задача | Параметры | |---|---| | Выбрать тип записей | post_type | | Ограничить количество | posts_per_page | | Пагинация | paged | | Сортировка | orderby, order | | Фильтр по таксономии | tax_query | | Фильтр по метаполям | meta_query | | Оптимизация списков без пагинации | no_found_rows |

    Пример tax_query: вывести фильмы только жанра comedy.

    CPT: кастомные типы записей как основа доменной модели

    Custom Post Type (CPT) нужен, когда “запись” и “страница” не описывают вашу сущность. Примеры:

  • товары
  • вакансии
  • события
  • фильмы
  • Документация:

  • register_post_type
  • Регистрация CPT

    Минимально практичный пример CPT movie (в плагине, на хуке init).

    Ключевые аргументы:

  • public: должен ли тип быть доступен на фронтенде.
  • has_archive: нужен ли архив example.com/movies/.
  • show_in_rest: делает тип доступным для блочного редактора и REST API.
  • supports: какие стандартные поля UI включить.
  • rewrite: человекопонятный URL.
  • Связь CPT с шаблонами темы

    Из статьи про иерархию шаблонов следует:

  • одиночная запись CPT movie будет искать single-movie.php (или templates/single-movie.html в блочной теме)
  • архив CPT movie будет искать archive-movie.php (или templates/archive-movie.html)
  • Поэтому регистрация CPT в плагине и создание соответствующих шаблонов в теме дают “чистую” архитектуру: сущность живёт независимо, а тема отвечает за отображение.

    Rewrite и необходимость сброса правил

    После добавления или изменения rewrite для CPT или таксономии иногда нужно сбросить правила постоянных ссылок.

    Практика:

  • в разработке можно просто зайти в Настройки → Постоянные ссылки и нажать “Сохранить”
  • в коде сброс (flush_rewrite_rules) делают осторожно и не на каждом запросе
  • Справочник:

  • flush_rewrite_rules
  • Таксономии: классификация и фильтрация

    Таксономия нужна для группировки и фильтрации записей.

  • встроенные таксономии: рубрики (category) и метки (post_tag)
  • кастомные: жанры, бренды, города, навыки
  • Документация:

  • register_taxonomy
  • Регистрация таксономии для CPT

    Пример: таксономия genre для CPT movie.

    Ключевые аргументы:

  • hierarchical: если true, таксономия будет вести себя как рубрики (иерархия).
  • show_in_rest: важно для Gutenberg и REST.
  • Как таксономии влияют на Template Hierarchy

    Для таксономии genre WordPress может использовать:

  • taxonomy-genre.php
  • taxonomy.php
  • archive.php
  • index.php
  • А для конкретного термина (в зависимости от правил и версии) будут применяться более специфичные варианты. Практический вывод тот же: вы можете точечно переопределять вывод без условных операторов внутри одного огромного шаблона.

    Метаполя: дополнительные данные у записей, терминов и пользователей

    Метаданные (meta) это “дополнительные поля”, привязанные к объекту.

  • postmeta: мета записи
  • termmeta: мета термина
  • usermeta: мета пользователя
  • Чаще всего в проектах начинают с метаполей записей.

    Документация:

  • get_post_meta
  • update_post_meta
  • Быстрый доступ к метаполю в шаблоне

    Пример: получить рейтинг фильма.

    Справочники:

  • wp_verify_nonce
  • esc_attr
  • Важно про безопасность и качество:

  • nonce защищает от CSRF
  • current_user_can проверяет права
  • sanitize и приведение типов защищают от мусора в базе
  • > Замечание: для современных проектов часто удобнее использовать show_in_rest и делать поля доступными для блоков, но метабоксы остаются актуальными для быстрых внутренних админок и legacy-проектов.

    Как собрать всё вместе: минимальная “вертикаль” функциональности

    Типичная архитектура под задачу “Фильмы” выглядит так.

  • Плагин регистрирует CPT movie и таксономию genre на init.
  • Плагин регистрирует метаполя и правила доступа.
  • Тема добавляет шаблоны single-movie.php и archive-movie.php (или соответствующие templates/*.html в блочной теме).
  • Для архивов и поиска тема и плагин совместно управляют запросами через pre_get_posts и/или вторичные WP_Query.
  • Так вы достигаете разделения ответственности: данные и бизнес-логика не зависят от темы, а внешний вид не “зашит” в плагин.

    Типовые ошибки и как их избегать

  • Регистрация CPT в теме: при смене темы “пропадает” сущность в UI.
  • Изменение главного запроса без is_main_query: ломаются админка, REST или вложенные запросы.
  • Использование метаполей без экранирования в шаблоне: риск XSS.
  • Отсутствие nonce и capability checks при сохранении мета: риск подмены данных.
  • Непонимание связи с шаблонами: CPT создан, но нет single-{post_type} или блочного шаблона, поэтому вывод выглядит “как попало”.
  • Что дальше по курсу

    Следующие логические шаги после этой статьи.

  • Углубление в разработку плагинов: страницы настроек, REST endpoints, безопасность, структура кода.
  • Углубление в разработку тем: ассеты, поддержка блоков, theme.json, интеграция данных CPT в шаблоны и паттерны.
  • Производительность: кэширование, оптимизация запросов WP_Query`, индексация meta и архитектурные ограничения метаполей.
  • 4. Разработка плагинов: структура, админка, настройки, REST API и шорткоды

    Разработка плагинов: структура, админка, настройки, REST API и шорткоды

    Плагин в WordPress — это упакованная функциональность, которая должна работать независимо от активной темы. В предыдущих статьях курса мы уже разобрали:

  • как WordPress загружается и в каком порядке подключаются расширения
  • как устроена шаблонная система и почему представление держат в теме
  • как через хуки и API регистрируют сущности (CPT, таксономии, метаполя) и управляют запросом
  • Теперь соберём всё это в практическую “вертикаль” именно на уровне плагина: структура, загрузка кода, админка, настройки, REST API и шорткоды.

    !Где и на каких хуках живёт код плагина

    Что обязательно должно быть в плагине, а что нельзя

    Плагин подходит для:

  • регистрации CPT, таксономий, метаполей
  • интеграций (платежи, внешние API, webhooks)
  • кастомной бизнес-логики (правила, статусы, обработка форм)
  • REST API endpoints
  • шорткодов и блоков
  • страниц настроек и административных экранов
  • Тема подходит для:

  • шаблонов и их частей
  • CSS/JS оформления
  • “склейки” вывода (например, как показать метаполя на single-{post_type}.php)
  • Ключевое правило: если функциональность должна пережить смену темы — ей место в плагине.

    Минимальная структура плагина

    Плагин — это папка в wp-content/plugins, внутри которой есть главный PHP-файл с заголовком.

    !Типичная структура проекта плагина

    Пример структуры:

  • my-movies-plugin/
  • - my-movies-plugin.php - uninstall.php - includes/ - admin/ - public/ - assets/

    Заголовок плагина

    Главный файл должен содержать “шапку” (это то, что WordPress читает в списке плагинов).

    defined('ABSPATH') || exit; — базовая защита от прямого запуска файла.

    Документация:

  • Plugin Handbook
  • Plugin Headers
  • Загрузка кода плагина: точка входа и организация файлов

    Для поддерживаемости важно отделять:

  • инициализацию (подписки на хуки)
  • админскую часть (меню, настройки, таблицы)
  • публичную часть (шорткоды, фронтенд-ассеты)
  • инфраструктуру (логирование, интеграции, HTTP-клиент)
  • Практический минимализм без усложнений:

    Когда проект растёт, обычно переходят к классам, неймспейсам и автозагрузке, но это имеет смысл, когда у вас реально появляется много модулей.

    Жизненный цикл плагина: активация, деактивация, удаление

    В WordPress есть три разных события:

  • активация — плагин включили
  • деактивация — плагин выключили
  • удаление — плагин удалили (через интерфейс)
  • Активация и деактивация

    Типовые задачи на активации:

  • создать опции со значениями по умолчанию
  • подготовить правила постоянных ссылок, если вы добавляете rewrite (например, CPT)
  • Хуки:

  • register_activation_hook
  • register_deactivation_hook
  • Пример:

    Важно: flush_rewrite_rules() нельзя вызывать на каждом запросе — это тяжёлая операция.

    Документация:

  • flush_rewrite_rules
  • Удаление (uninstall)

    Удаление — это отдельный сценарий. Если вы хотите удалять опции и служебные данные, используйте uninstall.php.

    Документация:

  • Uninstall Methods
  • Админка: меню и страница настроек

    Админская часть обычно решает две задачи:

  • предоставить UI управления
  • обеспечить безопасное сохранение данных
  • Добавление пункта меню

    Для добавления страницы в админке используется хук admin_menu и функция add_menu_page или add_options_page.

    Документация:

  • admin_menu
  • add_options_page
  • Пример: страница настроек в разделе “Настройки”:

    manage_options — capability (право), обычно доступно администраторам. Capability — это проверка прав текущего пользователя.

    Документация:

  • Roles and Capabilities
  • current_user_can
  • Settings API: правильный способ хранить и валидировать настройки

    Настройки обычно хранятся в таблице wp_options и доступны через:

  • get_option
  • update_option
  • Но для админ-форм лучше использовать Settings API, потому что он задаёт структуру:

  • где регистрируются опции
  • как они валидируются (sanitize)
  • как отображаются поля
  • Документация:

  • Settings API
  • register_setting
  • Регистрация опции и sanitize callback

    Пример: одна опция-массив mmp_settings.

    Здесь важно:

  • sanitize_callback — это функция, которая приводит данные к ожидаемому формату
  • intval — приводит значение к целому числу
  • max и min — ограничивают диапазон, чтобы не получить “100000 элементов на странице”
  • Рендеринг полей

    Что здесь важно с точки зрения архитектуры:

  • используем WP_Query, как в предыдущей статье, но возвращаем JSON вместо HTML
  • permission_callback принимает решение о доступе, и это часть контракта безопасности
  • ограничиваем per_page, чтобы endpoint нельзя было использовать для перегрузки сервера
  • Документация:

  • WP_REST_Request
  • rest_ensure_response
  • Пример: защищённый POST endpoint

    Если endpoint изменяет данные, он должен быть защищён:

  • capability check (например, право редактировать записи)
  • корректная аутентификация (например, cookie auth в админке или Application Passwords)
  • Документация:

  • Application Passwords
  • Пример permission callback:

    И регистрация маршрута (схематично):

    Шорткоды: быстрый способ добавить функциональность в контент

    Шорткод — это текстовая конструкция вида [...], которая заменяется результатом функции. Это простой механизм, который часто используют для:

  • вставки списков (товары, события, вакансии)
  • небольших виджетов (CTA, форма, счетчик)
  • совместимости с классическим редактором
  • Документация:

  • Shortcode API
  • add_shortcode
  • Пример: шорткод со списком фильмов

    Практические правила шорткодов:

  • шорткод должен возвращать строку, а не печатать через echo
  • учитывайте, что пользовательские атрибуты нужно приводить к типам и ограничивать
  • экранируйте вывод, потому что он уходит на фронтенд
  • Документация:

  • shortcode_atts
  • esc_html
  • Безопасность плагина: минимальный обязательный набор

    Права пользователя

    Всегда проверяйте capability:

  • на админ-страницах
  • в обработчиках сохранения
  • в REST permission_callback
  • Документация:

  • current_user_can
  • Nonce (защита от CSRF)

    Если вы обрабатываете формы вручную (не через options.php), используйте nonce:

  • wp_nonce_field
  • wp_verify_nonce
  • Экранирование вывода

    На фронтенде и в админке экранируйте всё, что может содержать пользовательский ввод:

  • esc_html для текста
  • esc_attr для атрибутов
  • esc_url для ссылок
  • Документация:

  • Data Validation
  • Data Sanitization
  • Data Escaping
  • Как плагин связывается с темой и шаблонами

    Чистая архитектура выглядит так:

  • Плагин регистрирует CPT movie, таксономии и метаполя на init.
  • Тема добавляет single-movie.php и archive-movie.php (или templates/*.html в блочной теме).
  • Плагин добавляет:
  • - REST endpoints для внешних интеграций - шорткоды для вставки в контент - настройки, которые управляют поведением

    Так вы не “зашиваете” разметку в плагин и не теряете функциональность при смене темы.

    Частые ошибки при разработке плагинов

  • Делать тяжёлые операции на каждом запросе вместо активации или cron.
  • Вызывать flush_rewrite_rules() в init или в любом хуке фронтенда.
  • Не проверять current_user_can на админ-страницах и в REST.
  • Не валидировать и не ограничивать параметры REST и шорткодов.
  • Печатать echo в шорткоде вместо return.
  • Что дальше по курсу

    После базовой “механики” плагинов логично углубляться в темы, которые повышают качество проекта:

  • архитектура кода плагина: сервисы, контейнеры, разделение слоёв
  • безопасность: валидация входных данных, права, политика доступа в REST
  • производительность: кеширование результатов запросов, оптимизация WP_Query
  • интеграция с блоками: динамические блоки, вариации блоков, data stores
  • 5. Фронтенд темы: стили, скрипты, сборка, Gutenberg и блоки

    Фронтенд темы: стили, скрипты, сборка, Gutenberg и блоки

    Фронтенд темы в WordPress — это управляемая система подключения CSS и JavaScript, которая должна быть:

  • предсказуемой (понятно, что и где подключается)
  • совместимой (с ядром, плагинами, дочерними темами)
  • производительной (не грузить лишнее)
  • дружелюбной к редактору блоков (Gutenberg) и Full Site Editing
  • В предыдущих статьях курса мы уже разобрали архитектуру и жизненный цикл WordPress, шаблонную систему (классические и блочные темы) и API уровня PHP (хуки, WP_Query, CPT, мета). Теперь “приземлим” эти знания на практику фронтенда темы: как правильно подключать ассеты, как организовать сборку, и как учитывать блоки.

    !Где именно подключать стили и скрипты темы в жизненном цикле

    Как WordPress управляет ассетами

    WordPress не предполагает “подключать файлы напрямую”. Вместо этого он предоставляет очередь ассетов (Scripts API): вы регистрируете и подключаете стили и скрипты через функции, указывая зависимости и версию.

    Ключевые понятия:

  • Handle — уникальное имя ассета, по которому WordPress управляет подключением.
  • Dependencies — список handle-ов, которые должны загрузиться раньше.
  • Version — строка версии для cache busting.
  • Hooks — точки жизненного цикла, где вы подключаете ассеты.
  • Документация:

  • wp_enqueue_style
  • wp_enqueue_script
  • Scripts API
  • Базовая практика: подключение стилей и скриптов на фронтенде

    На фронтенде тема чаще всего подключает ассеты на хуке wp_enqueue_scripts.

    Подключение CSS

    Пример подключения основного CSS темы:

    Почему это хороший шаблон:

  • get_stylesheet_directory_uri() корректен для дочерней темы.
  • filemtime() помогает автоматически менять версию при изменении файла и избегать проблем кеша.
  • Документация:

  • get_stylesheet_directory_uri
  • get_stylesheet_directory
  • Подключение JavaScript

    Пример подключения фронтенд-скрипта:

    Практические принципы:

  • Подключайте скрипты в футере, если они не нужны для ранней отрисовки.
  • Держите handle уникальными (обычно используют префикс темы).
  • Разделение фронтенда и редактора блоков

    Новички часто смешивают:

  • стили фронтенда
  • стили редактора
  • “общие” стили блоков
  • В WordPress для этого есть разные хуки.

    Какие хуки использовать

  • wp_enqueue_scripts — ассеты фронтенда.
  • enqueue_block_assets — ассеты, которые нужны и на фронтенде, и в редакторе блоков.
  • enqueue_block_editor_assets — ассеты только редактора.
  • Документация:

  • wp_enqueue_scripts
  • enqueue_block_assets
  • enqueue_block_editor_assets
  • Общие стили для блоков

    Если у вас есть CSS, который должен применяться и в редакторе, и на сайте (например, стили вашей дизайн-системы или выравнивания), используйте enqueue_block_assets.

    Стили только для редактора

    Чтобы редактор выглядел ближе к фронтенду, WordPress поддерживает editor styles.

    1) Включаем поддержку:

    2) Подключаем файл стилей редактора:

    Документация:

  • add_theme_support
  • add_editor_style
  • Gutenberg и блоки: что важно теме на фронтенде

    Даже если тема не регистрирует собственные блоки, она почти всегда должна учитывать поведение блоков:

  • блоки имеют собственные классы и структуру
  • многие блоки приходят со стилями ядра
  • часть стилей задаётся через theme.json
  • Здесь важно не “воевать” с блоками глобальными селекторами, а проектировать стили как систему.

    Theme supports, которые часто нужны

    Поддержка широкого выравнивания и других возможностей влияет на то, какие опции доступны в редакторе и как блоки ведут себя на фронтенде.

    Документация:

  • Theme Support
  • Варианты стилей для блоков

    Если вы хотите дать пользователю выбор “стилей блока” (например, для цитаты или кнопки), тема может регистрировать стили блока.

    Документация:

  • register_block_style
  • Принцип архитектуры:

  • тема определяет варианты оформления
  • контент остаётся контентом
  • пользователь выбирает стиль на уровне блока, а не “ломает” разметку вручную
  • theme.json как центр управления стилями в блок-темах и гибридных темах

    В Full Site Editing и блочных темах theme.json — это декларативный слой:

  • настройки редактора (что разрешено пользователю)
  • глобальные стили
  • стили для конкретных блоков
  • Документация:

  • Global Settings and Styles (theme.json)
  • Даже в классической теме theme.json может быть полезен как “источник правды” для палитры, типографики и базовых отступов.

    Практические рекомендации:

  • Лучше описывать палитру и типографику в theme.json, чем разносить по файлам.
  • Ограничивайте “произвольные” настройки, если проект требует консистентности.
  • Не дублируйте то, что ядро уже даёт через style engine, без необходимости.
  • Сборка фронтенда: когда нужна и как встроить в тему

    Есть два жизнеспособных подхода.

    Подход без сборки

    Подходит для небольших тем:

  • пишете CSS и JS вручную
  • подключаете через enqueue
  • минимизируете зависимость от Node.js
  • Плюс: меньше инструментов. Минус: сложнее масштабировать, нет автоматической оптимизации.

    Подход со сборкой

    Нужен, если:

  • много модулей JS
  • используете современный JS
  • нужна минификация, разделение на чанки
  • хотите единый процесс сборки для блоков и фронтенда
  • Для WordPress-экосистемы часто используют @wordpress/scripts.

    Документация:

  • @wordpress/scripts
  • Принцип интеграции со сборкой:

  • Исходники лежат в src/.
  • Сборка кладёт результат в assets/ или build/.
  • Тема подключает только результат сборки.
  • !Как сборка превращается в подключаемые файлы темы

    Версионирование и кеш

    У WordPress есть параметр ver у ассетов. Его задача — помочь браузеру понять, что файл изменился.

    Рабочие стратегии:

  • filemtime() в разработке и на проектах без CDN
  • фиксированная версия темы (например, из wp_get_theme()->get('Version')) для релизов
  • Документация:

  • wp_get_theme
  • Подключение ассетов “только когда нужно”

    Производительность темы сильно зависит от того, грузите ли вы лишнее.

    Практики условного подключения:

  • подключать специфичный CSS только на нужных шаблонах
  • подключать тяжёлый JS только там, где реально есть интерактивность
  • проверять наличие блоков в контенте
  • Документация:

  • Conditional Tags
  • has_block
  • Пример: подключить скрипт только если на странице есть определённый блок.

    Зависимости скриптов, данные с сервера и перевод

    Зависимости

    Если ваш скрипт зависит от библиотек, поставляемых WordPress, указывайте их в параметре dependencies.

    Пример: подключение скрипта, который рассчитан на наличие wp-api-fetch (часто нужно для запросов к REST API).

    Документация:

  • wp-api-fetch
  • Передача данных в JS

    Тема часто должна передать JS-настройки или URL в REST.

    Классический способ — wp_localize_script.

    Документация:

  • wp_localize_script
  • rest_url
  • Перевод JS

    Если вы пишете JS, который должен поддерживать переводы, используйте wp_set_script_translations.

    Документация:

  • wp_set_script_translations
  • Отладка фронтенд-ассетов

    Типовые проблемы: “скрипт не загружается”, “стили переопределились”, “в редакторе одно, на фронтенде другое”.

    Рабочие инструменты:

  • WP_DEBUG и SCRIPT_DEBUG
  • просмотр очереди ассетов через Query Monitor
  • Документация:

  • Debugging in WordPress
  • Query Monitor
  • Практический принцип: сначала проверьте, какой именно handle подключён, в каком хуке и какие зависимости.

    Архитектурная связка с остальным курсом

    Эта тема напрямую соединяет предыдущие материалы:

  • из архитектуры WordPress вы берёте понимание жизненного цикла и хуков, чтобы подключать ассеты в правильных точках
  • из шаблонной системы вы берёте правило разделения: шаблон отвечает за структуру страницы, а фронтенд-ассеты — за оформление и поведение
  • из статьи про API вы берёте REST API, CPT и мета-данные, которые фронтенд-скрипты могут использовать через wp-api-fetch
  • из статьи про плагины вы видите, как тема и плагин разделяют ответственность: тема стилизует и подключает UI, а плагин поставляет данные и бизнес-логику
  • Ключевая цель на практике: сделать тему, которая корректно работает с блоками, предсказуемо подключает CSS и JS, и легко масштабируется за счёт сборки и модульности.

    6. Безопасность и качество: валидация, nonce, права, стандарты и тестирование

    Безопасность и качество: валидация, nonce, права, стандарты и тестирование

    В предыдущих статьях курса мы разобрали архитектуру WordPress, хуки и жизненный цикл, шаблонную систему, API уровня PHP (CPT, таксономии, мета), разработку плагинов, а также подключение ассетов и работу с блоками. Следующий шаг в глубокой разработке — научиться писать код так, чтобы он был одновременно:

  • безопасным (не даёт атакующему выполнить чужой код, украсть данные или изменить сайт)
  • качественным (поддерживаемым, предсказуемым, тестируемым и совместимым с экосистемой WordPress)
  • Эта статья — практический набор правил и шаблонов: валидация входных данных, nonce и защита от CSRF, проверка прав доступа, стандарты кодирования и тестирование.

    !Пайплайн безопасной обработки данных в WordPress

    Модель угроз: откуда приходят данные и где они опасны

    В WordPress почти вся безопасность сводится к дисциплине обработки данных в нескольких точках.

    Источники входных данных

  • _POST (формы, настройки, метабоксы)
  • raw = isset(_POST['items_per_page'] : '';
  • raw); // sanitize: делаем число >= 0

    if (value > 100) { wp_die('Некорректное значение.'); } php if (!current_user_can('manage_options')) { wp_die('Недостаточно прав.'); } php if (!current_user_can('edit_post', _POST['mmp_nonce'])) { wp_die('Nonce отсутствует.'); }

    if (!wp_verify_nonce(wpdb и подготовленные запросы

    Большинство задач решается через API WordPress (WP_Query, мета, опции). Но иногда нужен низкоуровневый SQL. В этом случае главное правило:

  • никогда не склеивайте SQL из пользовательских строк
  • Документация:

  • wpdb->prepare
  • Пример безопасного запроса:

    Обратите внимание:

  • absint санитизирует число
  • wpdb->postmeta, а не строкой
  • Экранирование вывода в теме и плагине: защита от XSS

    XSS обычно появляется там, где разработчик “доверяет данным из базы”. В WordPress это особенно опасно, потому что контент и мета могут приходить из:

  • импорта
  • сторонних плагинов
  • редактора блоков
  • REST запросов
  • Справочники:

  • esc_html
  • esc_attr
  • esc_url
  • wp_kses_post
  • Шпаргалка по контекстам

    | Контекст | Что использовать | |---|---| | текст между тегами | esc_html | | HTML-атрибут | esc_attr | | URL в ссылке/редиректе | esc_url и wp_safe_redirect | | ограниченный HTML (как у контента) | wp_kses_post |

    Документация по безопасным редиректам:

  • wp_safe_redirect
  • Пример вывода метаполя в шаблоне

    Даже такие простые тесты полезны: они фиксируют правила, которые иначе “уплывут” со временем.

    Что тестировать в контексте безопасности

  • функции санитизации и валидации
  • permission_callback REST endpoint-ов
  • обработчики save_post_* и их ранние return при отсутствии nonce/прав
  • генерацию и обработку настроек (Settings API)
  • Итоговый чеклист для тем и плагинов

  • Всегда проверяйте права через current_user_can.
  • Всегда используйте nonce для действий, изменяющих данные.
  • Санитизируйте и валидируйте входные данные.
  • Экранируйте данные в момент вывода в зависимости от контекста.
  • Для SQL используйте $wpdb->prepare.
  • Подключайте PHPCS с WordPress Coding Standards.
  • Пишите тесты хотя бы на критичные правила безопасности и бизнес-логики.
  • Эта дисциплина напрямую связывает всё, что было в курсе раньше: хуки и жизненный цикл определяют где проверять, API определяют чем проверять, а темы и шаблоны определяют в каком контексте выводить данные безопасно.

    7. Производительность и релиз: кеширование, оптимизация, локализация, публикация

    Производительность и релиз: кеширование, оптимизация, локализация, публикация

    Проект на WordPress становится по-настоящему профессиональным, когда он не только работает функционально, но и:

  • быстро отвечает пользователю
  • масштабируется по нагрузке
  • предсказуемо обновляется
  • корректно локализуется
  • выпускается как релиз с понятным жизненным циклом
  • Эта статья связывает предыдущие темы курса в одну практику.

  • Архитектура и жизненный цикл объясняют, где и когда ваш код выполняется и как это влияет на скорость.
  • WP APIs (хуки, WP_Query, мета) объясняют, чем вы создаёте функциональность и где можно допустить дорогие ошибки.
  • Плагины и фронтенд темы показывают, как устроены ассеты, REST и админка.
  • Безопасность и качество задают дисциплину: санитизация, права, стандарты.
  • Теперь добавим ещё один слой дисциплины: производительность и релизный процесс.

    !Карта слоёв кеширования и где именно находится WordPress

    Как думать о производительности в WordPress

    Производительность почти всегда упирается в три группы затрат:

  • база данных и запросы (WP_Query, мета-запросы, options)
  • PHP-логика (циклы, фильтры, сериализация данных, сторонние API)
  • фронтенд (CSS/JS, изображения, шрифты, блоки)
  • Правильный порядок работы:

  • Измерить: понять, где тормозит.
  • Устранить горячие точки: запросы, мета, лишние ассеты.
  • Добавить кеширование: не “ускорять вычисления”, а “не делать их повторно”.
  • Проверить, что кеш инвалидация корректна.
  • Закрепить результат релизом.
  • Измерение и диагностика

    Инструменты уровня WordPress

  • Query Monitor для поиска:
  • - медленных SQL-запросов - ошибок PHP - хуков и очереди ассетов - HTTP-запросов (внешние API)
  • WP_DEBUG и WP_DEBUG_LOG для логирования в разработке
  • Практическая привычка: сначала откройте проблемную страницу с Query Monitor и посмотрите:

  • сколько SQL-запросов
  • какие самые долгие запросы
  • есть ли повторяющиеся запросы
  • не делает ли тема или плагин внешние HTTP-запросы на каждый просмотр
  • Измерение на фронтенде

    Для пользовательской скорости важны метрики загрузки страницы, а не только серверное время.

  • PageSpeed Insights и отчёты Core Web Vitals
  • вкладка Performance в DevTools
  • Даже если сервер отвечает быстро, “тяжёлые” изображения, шрифты и JS могут сделать сайт визуально медленным.

    Кеширование: что кешировать и где

    Быстрое правило выбора техники

  • Если результат дорогой (запросы, агрегации, внешний API) и повторяется, кешируйте его.
  • Если данные меняются часто и “в реальном времени”, кеш должен быть коротким или с точной инвалидацией.
  • Transients API: кеш с TTL в WordPress

    Transients — удобный способ хранить результат вычислений с временем жизни.

    Документация:

  • get_transient
  • set_transient
  • delete_transient
  • Пример: кешируем список “топ фильмов” на 10 минут.

    Object Cache: кеш в памяти и почему он меняет картину

    WordPress поддерживает object cache. Если подключён persistent object cache (например Redis), кеш может жить между запросами.

    Базовые функции:

  • wp_cache_get
  • wp_cache_set
  • wp_cache_delete
  • Практический смысл:

  • без persistent object cache кеш очищается каждый запрос
  • с Redis/Memcached кеш может реально разгрузить базу и ускорить сайт под нагрузкой
  • Важно: как разработчик темы/плагина вы обычно не “устанавливаете Redis”, но вы можете писать код так, чтобы он корректно работал и без него, и с ним.

    Page cache и CDN: что это значит для разработчика

    Page cache (серверный кеш целой HTML-страницы) и CDN часто дают наибольший прирост.

    Что важно помнить в коде:

  • не делайте персонализированный вывод “для всех” (например, приветствие по имени) без учёта кеша
  • разделяйте публичные и персональные части (персональные чаще грузят AJAX/REST после загрузки)
  • не полагайтесь на то, что ваш PHP-код “всегда выполнится”: при page cache он может вообще не запускаться
  • Оптимизация запросов и данных

    Опасные места: meta_query и сортировка по метаполям

    meta_query и сортировки по meta_value часто становятся медленными на больших объёмах данных, потому что таблица wp_postmeta быстро разрастается.

    Практики смягчения:

  • избегайте сложных OR в meta_query, если можно упростить фильтр
  • храните данные в подходящем типе и сортируйте как meta_value_num, если это число
  • используйте кеширование результатов списков
  • Не тащите лишнее: fields, posts_per_page, no_found_rows

    Если вам нужны только ID или только ссылки, не запрашивайте целые объекты.

  • fields => ids для списков ID
  • no_found_rows => true когда пагинация не нужна
  • разумный posts_per_page и ограничение пользовательских параметров в REST и шорткодах
  • Документация:

  • WP_Query
  • Опции и autoload: скрытая причина медленных запросов

    WordPress загружает часть опций “автоматически” на каждом запросе. Если в wp_options накопится много тяжёлых autoload-опций, сайт может тормозить даже без ваших запросов.

    Практические рекомендации для плагинов:

  • не храните большие массивы в опциях без необходимости
  • аккуратно проектируйте настройки: лучше несколько маленьких значений, чем один гигантский blob
  • используйте transients или object cache для расчётных данных, а опции оставляйте для конфигурации
  • Оптимизация фронтенда темы

    Эта часть напрямую опирается на предыдущую статью про ассеты.

    Подключайте ассеты условно

    Самый частый и самый простой выигрыш: не грузить то, что не нужно.

    Инструменты:

  • Conditional Tags
  • has_block
  • Пример: грузим улучшения галереи только там, где есть галерея.

    Версии ассетов и кеш браузера

    Управление параметром ver у CSS/JS — основа стабильных релизов.

    Практики:

  • filemtime() удобно в разработке и в небольших проектах
  • версия темы/плагина удобна в релизах
  • Документация:

  • wp_get_theme
  • Изображения и медиа

    Даже при идеальном PHP-коде изображения могут “убить” скорость.

    Рекомендации для тем:

  • используйте встроенные размеры изображений (the_post_thumbnail и srcset)
  • не выводите оригиналы там, где нужен превью размер
  • избегайте фоновых изображений без адаптивных вариантов
  • Документация:

  • Post Thumbnails
  • Локализация: i18n и l10n как часть релиза

    Локализация — это не “перевести пару строк”, а соблюдать контракт WordPress: строки должны быть извлекаемыми, контекстными и связаны с доменом переводов.

    Документация:

  • Internationalization
  • Базовые правила локализации

  • любые строки UI в теме/плагине должны проходить через функции перевода
  • текстовый домен должен быть единым и совпадать с темой/плагином
  • пользовательский ввод не переводят, переводят только интерфейс
  • Ключевые функции:

  • __ возвращает переведённую строку
  • _e печатает переведённую строку
  • esc_html__, esc_attr__ сразу учитывают контекст экранирования
  • Пример в плагине:

    Загрузка переводов в плагине

    Документация:

  • load_plugin_textdomain
  • Пример:

    Почему plugins_loaded подходит:

  • плагины уже загружены
  • локализация инициализируется достаточно рано для админки и фронтенда
  • Локализация в теме

    Документация:

  • load_theme_textdomain
  • Пример:

    Переводы для JavaScript

    Если вы используете JS (особенно в блоках), переводы должны быть доступны и там.

    Документация:

  • wp_set_script_translations
  • Релиз: как упаковать тему или плагин, чтобы обновления были безопасными

    Релиз в WordPress — это сочетание:

  • версионирования
  • совместимости (PHP, WordPress)
  • правильной упаковки файлов
  • предсказуемых миграций данных
  • документации для пользователей
  • !Пайплайн от коммита до обновления на сайте

    Версионирование и совместимость

    Практические правила:

  • повышайте версию при любом изменении поведения, API или UI
  • фиксируйте минимальную версию PHP и WordPress, которую поддерживаете
  • поддерживайте обратную совместимость или явно описывайте breaking changes в changelog
  • Для плагинов версия обычно хранится в заголовке главного файла. Для тем — в style.css.

    Миграции и изменения данных

    Если новая версия меняет структуру данных (опции, мета, кастомные таблицы), нужен управляемый апгрейд.

    Принцип:

  • храните текущую версию схемы в опции
  • при обновлении выполняйте миграцию один раз
  • Инструменты хранения настроек:

  • get_option
  • update_option
  • “Не ломайте сайт”: стабильность при отключении

    Плагин должен корректно переживать:

  • деактивацию
  • повторную активацию
  • удаление
  • И это связано с производительностью: тяжёлые операции делайте на активации, а не на каждом запросе.

    Документация:

  • register_activation_hook
  • register_deactivation_hook
  • Uninstall Methods
  • Подготовка к публикации на WordPress.org

    Если вы публикуете плагин в каталоге WordPress.org, учитывайте:

  • требования и правила каталога
  • структуру readme.txt
  • корректное указание лицензии
  • Документация:

  • Detailed Plugin Guidelines
  • How Your Readme.txt Works
  • Если вы публикуете тему:

  • следуйте требованиям ревью тем
  • Документация:

  • Theme Review Guidelines
  • Сборка и поставка ассетов

    Если вы используете сборку (например, @wordpress/scripts), важно, чтобы в релиз попадали готовые файлы, которые будут на сервере пользователя.

    Практическая дисциплина:

  • исходники в src/
  • результат сборки в build/ или assets/
  • WordPress подключает только результат сборки
  • Если вы публикуете на WordPress.org, подумайте заранее:

  • какие папки должны попасть в релиз
  • какие папки не должны попадать (например, node_modules)
  • Регрессия производительности как часть релиза

    Перед публикацией версии проверьте:

  • не добавились ли новые медленные запросы
  • не вырос ли объём подключаемых CSS/JS
  • корректно ли работает кеш и инвалидация
  • не сломались ли переводы
  • Минимальный практический чек:

  • Открыть несколько ключевых страниц с Query Monitor.
  • Сравнить количество и время запросов до и после.
  • Проверить, что нет новых PHP warning/error.
  • Проверить страницу настроек, REST endpoints и шорткоды.
  • Частые ошибки, которые делают сайт медленным и релизы опасными

  • Кеширование без инвалидации: пользователи видят устаревшие данные.
  • flush_rewrite_rules() на каждом запросе вместо активации.
  • Тяжёлые meta_query и сортировки по мета без кеша.
  • Подключение всех ассетов на всех страницах.
  • Строки без i18n: невозможно сделать переводы.
  • Релизы без контроля версии и changelog: невозможно понять, что изменилось.
  • Итог

    Производительность и релиз — это продолжение тем про архитектуру, API, фронтенд и безопасность.

  • Производительность начинается с измерения и дисциплины запросов.
  • Кеширование должно иметь стратегию инвалидации.
  • Фронтенд оптимизируется условными ассетами и правильными версиями.
  • Локализация должна быть встроена в код с самого начала.
  • Релиз должен быть воспроизводимым процессом: версия, сборка, проверка, публикация.