Небольшой собственный плагин
В предыдущей главе мы определяли функцию формы и не устанавливали случайные расширения. Теперь возьмём меньшую задачу, которую можно разобрать полностью: одинаковое пояснение о характере учебных примеров. Его нужно показывать в разных материалах и сохранять при смене темы. Создадим небольшой собственный плагин pw-workshop-tools. Результат урока — отдельный источник функции и понятное подключение к жизненному циклу WordPress.
Тема отвечает за представление, плагин — за выбранную возможность сайта. Если поместить функцию пояснения только в functions.php темы, переключение оформления может лишить страницы этого механизма. Содержимое останется в базе, но его специальная вставка перестанет работать. Плагин позволяет изменить оболочку независимо от функции. Основные требования к файлу расширения описаны в Plugin Handbook. Здесь нет Composer, сборщика JavaScript или внешней библиотеки: весь начальный пример находится в одном PHP-файле.
Полный файл первого расширения
В учебном WordPress создайте каталог wp-content/plugins/pw-workshop-tools/ и в нём pw-workshop-tools.php. Наш файл регистрирует shortcode, то есть именованную вставку содержимого. Полное содержимое начальной версии:
<?php
/**
* Plugin Name: PW Workshop Tools
* Description: Educational content helpers for Web Workshop.
* Version: 0.1.0
* Requires at least: 7.1
* Requires PHP: 8.3
*/
if (!defined('ABSPATH')) {
exit;
}
function pw_workshop_register_shortcodes(): void {
add_shortcode('pw_learning_note', 'pw_workshop_learning_note');
}
function pw_workshop_learning_note(): string {
$message = 'Учебный пример нужно выполнить в собственной копии проекта.';
return '<p class="pw-learning-note">' . esc_html($message) . '</p>';
}
add_action('init', 'pw_workshop_register_shortcodes');
Комментарий Plugin Name нужен WordPress для определения расширения. Проверка ABSPATH останавливает прямое исполнение файла вне обычного контекста движка; она не является системой авторизации, поскольку плагин здесь вообще не принимает запрос на изменение данных. Имена функций имеют собственный префикс. В PHP глобальное имя может столкнуться с другой функцией, поэтому короткое универсальное register() было бы плохим выбором даже для маленького примера.
add_shortcode связывает имя pw_learning_note с обработчиком. Обработчик возвращает строку, а не печатает её через echo. Это важно: WordPress вставляет возвращённое значение в нужное место содержимого. Непосредственная печать могла бы появиться не там, где ожидает редактор, и мешала бы последующей обработке. esc_html экранирует текст перед включением в HTML; наша фиксированная формулировка безопасна по содержимому, но сам приём пригодится для будущего расширяемого текста.
Вставка в материал
Активируйте плагин на отдельном стенде, затем откройте страницу «Как учиться». После списка действий добавьте штатный блок Shortcode с текстом [pw_learning_note]. Не вставляйте его в блок кода: там читатель должен видеть буквальный пример, а не результат функции. Также не нужна новая копия обычного абзаца с тем же предупреждением. Мы хотим, чтобы один источник текста обслуживал несколько осознанных мест вставки.
В предварительном просмотре ожидается один абзац с пояснением. Добавьте ту же вставку в запись image-shift и сравните вывод. Оба материала получают одинаковый текст, но не имеют общего тела статьи. Это полезное повторение одной функции. При изменении $message после обновления плагина оба места должны показать новую формулировку при свежем выводе страницы. Наличие серверного или промежуточного кеша может задержать отображение, поэтому кеш рассматривается отдельно от источника значения.
В этом примере shortcode не имеет атрибутов и не обрабатывает произвольный HTML между открывающим и закрывающим именем. Это намеренная узкая граница. Если добавить атрибут «уровень» или «курс», потребуется определить допустимые значения, обработать отсутствующие параметры и сформировать результат без небезопасной вставки. Не следует считать, что функция, возвращающая строку, уже реализует универсальный компонент. Для наших двух страниц одной фиксированной формулировки достаточно.
Когда выполняется регистрация
На init WordPress вызывает нашу функцию, а та регистрирует имя shortcode для последующей обработки. Действие не создаёт новую запись в базе и не печатает предупреждение при каждом запросе. Регистрация и использование разделены: если на странице нет [pw_learning_note], возвращаемый абзац не нужен. Это помогает понять будущие hooks. Подключение к этапу жизненного цикла сообщает, когда подготовить возможность; содержимое определяет, где посетитель её увидит.
Плагин не содержит activation hook, потому что в первом шаге ему не нужно создавать таблицы, роли или правила rewrite. Не добавляйте такие операции ради формальной полноты шаблона. Чем меньше скрытых изменений при активации, тем понятнее исходное состояние. В последующих уроках появится собственный тип материала, и тогда отдельно разберём обновление правил адресов. Очистка всех правил на каждом обычном запросе не должна становиться привычным побочным эффектом.
Отказ и переносимость функции
Рассмотрим деактивацию. Именованная вставка в содержимом остаётся, но обработчик больше не зарегистрирован. Не обещаем, что WordPress автоматически заменит её прежним текстом; нужно увидеть фактическое поведение используемого блока и обработчика. Поэтому для важной информации, без которой урок непонятен, такая зависимость требует решения о переносе содержимого. Наше пояснение дополняет текст, а не хранит единственный способ выполнить упражнение.
Переключите тему с pw-workshop на другую учебную тему, оставив плагин активным. Ожидается сохранение функции, хотя оформление абзаца может отличаться. Класс pw-learning-note не имеет собственных CSS-правил в плагине, и потому мы не обещаем одинаковую рамку или отступ. Это правильная граница между функцией и темой: текст доступен, а внешний вид относится к согласованному оформлению. При необходимости плагин может поставлять стили, но это отдельный шаг с собственной стоимостью ресурсов.
Другая ошибка — скопировать PHP-файл в каталог темы и одновременно оставить плагин активным. Два определения одних функций могут вызвать ошибку. Не используйте такое дублирование как способ «гарантировать» доступность. Приём состоит в единственном авторитетном источнике кода. Если требуется новая версия, замените файл плагина и увеличьте Version, сохранив старый снимок для сравнения. Содержимое страниц при этом не переносится в новый каталог.
Ожидаемый результат — активируемое учебное расширение и два места с одинаковым возвращаемым абзацем. PHP, WordPress и просмотры здесь не запускались; файл является подготовленным исходником. Перед реальным использованием надо подтвердить регистрацию, вывод и поведение при деактивации на выбранной среде. В следующем уроке добавим контролируемую точку изменения формулировки через filter, сохранив тот же shortcode и обязательное экранирование конечного текста.