Как я написал свой первый плагин для WordPress и что из этого вышло
Зачем писать плагин, если всё уже есть
Мне нужно было добавить на сайт кнопку «Поделиться в Telegram» с счётчиком. Стандартные плагины либо уродливые, либо тяжёлые, либо показывают рекламу своей премиум-версии. Я решил написать свой — маленький и аккуратный.
До этого я никогда не писал плагины для WordPress. Думал, это сложно — нужно знать хуки, API, архитектуру. На деле оказалось проще, чем я ожидал.
Структура плагина
Плагин — это просто PHP-файл с комментарием в начале. Я создал папку telegram-share в wp-content/plugins/, внутри файл telegram-share.php:
В начале файла — стандартный заголовок: название плагина, описание, версия, автор. Без этого WordPress не увидит плагин.
Дальше — функция, которая выводит кнопку под каждым постом. Использовал хук the_content. Просто добавил HTML с иконкой Telegram и ссылкой вида https://t.me/share/url?url=…
Счётчик я сделал через custom field: когда кто-то нажимает кнопку, JS отправляет запрос на admin-ajax.php, и число увеличивается. Без базы данных, без лишних плагинов.
Что пошло не так
Первая версия выводила кнопку даже на страницах админки. Я забыл проверить is_single(). Исправил.
Счётчик сбрасывался при обновлении поста. Потому что я хранил его в post_meta, а при сохранении поста WP перезаписывал мета-поля. Пришлось добавить проверку: если поле уже существует — не трогать.
Кэширование. WP Super Cache кешировал страницы, и счётчик не обновлялся. Пришлось добавить исключение для кнопки через JavaScript, чтобы она грузилась асинхронно.
Итог
Плагин работает, кнопка висит под каждой статьёй. Счётчик тикает. Кода — 40 строк PHP и 20 строк JavaScript.
Теперь я не боюсь писать плагины. Для простых задач — это быстрее, чем искать подходящий плагин в репозитории и бороться с его настройками.
Расскажу эту историю подробнее, потому что написание первого плагина развеяло мой страх перед внутренностями WordPress. Если ты думаешь, что плагины — это что-то сложное и доступное только «настоящим разработчикам» — этот текст для тебя.
Начну с того, что меня вообще подтолкнуло к идее написать свой плагин. Мне нужна была кнопка «Поделиться в Telegram» со счётчиком. Казалось бы, что может быть проще — в репозитории WordPress наверняка есть десятки таких плагинов. Но когда я начал искать, столкнулся с известной проблемой: либо плагин уродливый и навязчивый, либо тянет за собой кучу лишнего, либо подсовывает рекламу премиум-версии. А мне нужно было маленькое аккуратное решение под мою конкретную задачу. В какой-то момент я подумал: «А почему бы не написать самому?»
И тут же испугался. Мне казалось, что плагины — это сложная архитектура: хуки, API, экшены, фильтры, базы данных. Я откладывал это «на потом» несколько недель. А потом просто открыл документацию WordPress и понял, что плагин — это всего лишь PHP-файл с определённым заголовком в начале. Всё. Никакой магии. WordPress сам находит папку в wp-content/plugins, читает заголовок и показывает плагин в списке. Дальше — обычный PHP, который ты пишешь как обычную функцию.
Теперь про структуру подробнее. Я создал папку telegram-share в wp-content/plugins, а внутри — файл telegram-share.php. Первым делом в нём идёт стандартный заголовок: название плагина, описание, версия, автор. Это не просто комментарий — без него WordPress просто не увидит плагин в списке установленных. Заголовок заполняется специальным образом, в формате, который WordPress понимает. Потом начинается сам код: функция, которая выводит кнопку, и регистрация хука, который её вызывает.
Ключевой момент — понимание хуков. В WordPress есть хуки (hooks) — это точки, куда можно «повесить» свой код. Хук the_content срабатывает, когда WordPress выводит содержимое поста. Я повесил на него свою функцию, которая добавляет кнопку «Поделиться в Telegram» под текстом каждой статьи. Выглядит это просто: функция возвращает HTML с иконкой и ссылкой вида https://t.me/share/url?url=… а add_filter регистрирует эту функцию на хуке. Пять минут работы — и кнопка появляется на всех постах.
Про счётчик расскажу отдельно, потому что это была самая интересная часть. Мне нужно было, чтобы при нажатии кнопки число увеличивалось, и это число хранилось где-то. Решение без базы данных: я использовал custom field (мета-поле поста). Когда посетитель нажимает кнопку, JavaScript отправляет запрос на admin-ajax.php — стандартный обработчик AJAX в WordPress — и сервер увеличивает значение мета-поля. Никакой отдельной таблицы, никакого плагина для счётчиков. Всё через стандартные механизмы WordPress.
Кстати, про admin-ajax.php стоит знать одну важную вещь: для него нужно зарегистрировать обработчик через wp_ajax_ и wp_ajax_nopriv_ — второй нужен для неавторизованных пользователей. Это классическая грабля для новичков: обработчик работает у админа, но «молчит» у обычных посетителей, потому что забыли про nopriv-версию. Я на этой ошибке тоже поймался, прежде чем разобраться. Запомни на будущее: если AJAX-запрос не проходит у гостей — проверь, зарегистрирован ли обработчик через wp_ajax_nopriv_.
Теперь про то, что пошло не так. Первая моя ошибка — кнопка выводилась даже в админке, на страницах редактирования постов. Выглядело это нелепо. Проблема была в том, что я не проверил, выводится ли пост на самом сайте. Решение простое — добавить проверку is_single() перед выводом кнопки. Эта функция возвращает true только на страницах отдельных постов. После этого кнопка появилась только там, где нужно: под статьями на сайте.
Вторая ошибка — сброс счётчика при сохранении поста. Я хранил число в мета-поле, но WordPress при сохранении поста перезаписывает мета-поля, и счётчик обнулялся каждый раз, когда я редактировал статью. Пришлось добавить проверку: если поле уже существует — не трогать его. Это маленькая логическая правка, но именно такие нюансы всплывают, когда работаешь с WordPress «по-настоящему». Сборка на живых данных отличается от теоретических примеров из документации.
Третья проблема — кеширование. На сайте стоял WP Super Cache, и он кешировал страницы. Счётчик не обновлялся, потому что страница отдавалась из кеша со старым значением. Тут уже не поможет PHP — страница уже сгенерирована. Решение пришло со стороны JavaScript: я сделал так, чтобы значение счётчика подгружалось асинхронно, после загрузки страницы. Страница кешируется без актуального числа, а потом JS подставляет текущее значение через AJAX. Хитро, но работает.
Какие выводы я сделал из всего этого. Во-первых, плагин для простой задачи — это быстрее и надёжнее, чем поиск готового решения в репозитории. Пока ты переберёшь пять плагинов, будешь бороться с их настройками и рекламой, ты можешь написать своё за вечер. Во-вторых, не бойся ошибок — они нормальны и решаются. Каждая моя ошибка привела к пониманию какого-то механизма WordPress, и в следующий раз я уже знаю, где что искать.
Ещё один важный вывод — читай документацию и смотри, как устроены популярные плагины. Когда я писал свой первый плагин, я разбирал код какого-нибудь простого популярного плагина, чтобы увидеть, как правильно регистрировать хуки и что с чем связано. Это ускоряет обучение в разы. WordPress — это огромная экосистема с устоявшимися паттернами, и переизобретать их не нужно — достаточно следовать стандартам.
Отдельно про безопасность скажу пару слов, потому что плагины — это код, который выполняется на твоём сайте. Моя кнопка ничего не принимала от пользователей, кроме одного числа, но всё равно я выводил всё через esc_html и проверял, что число — это действительно число (absint). Если бы плагин принимал произвольные данные и выводил их без санитизации — это был бы вектор для XSS. Для маленького личного плагина это не критично, но привычка валидировать входные данные должна быть с первого дня.
Теперь про то, как я стал относиться к плагинам в целом. Раньше я ставил плагины на каждую мелочь: «а давай поставим кнопку, а давай добавим галерею». Теперь я смотрю на задачу и прикидываю: проще написать свою маленькую функцию или взять готовый плагин? Для простых задач — своё, для сложных и массовых (например, SEO-плагины, кеширование) — готовое, потому что там уже учтены тысячи нюансов. Это разумный баланс, к которому я пришёл через свой первый плагин.
Про объём кода скажу честно, чтобы снять ещё один страх: мой плагин — это около 40 строк PHP и 20 строк JavaScript. Всего 60 строк кода, которые решили конкретную задачу. Никаких сотен файлов, никаких классов на двадцать уровней. Для простых задач WordPress позволяет обходиться минимальным кодом. Это главное, что я хочу донести: плагин не обязан быть сложным, чтобы быть полезным.
Кстати, про документацию и поиск информации: не думай, что всё нужно держать в голове. Я до сих пор открываю справочник функций WordPress при каждом шаге. Ты же не обязан помнить сигнатуру каждой функции — достаточно знать, что она существует, и уметь её быстро найти. Для меня это был прорыв: перестать пытаться запомнить всё и начать просто использовать документацию как справочник.
Подведу итог. Написание первого плагина — это не страшно, а полезно. Ты разбираешься в том, как работает WordPress, изнутри, перестаёшь бояться «страшных» терминов вроде хуков и API и начинаешь понимать, что большинство задач решается десятком строк кода. И самое приятное — после первого плагина хочется писать ещё. Следующий раз будет уже не «первым», а просто работой. Я бы советовал каждому, кто ведёт сайт на WordPress, написать хотя бы один маленький плагин — это быстро, познавательно и освобождает от зависимости от чужих решений.
И пара слов про то, как тестировать плагин перед публикацией. Я не сразу выкатил его на основной сайт — сначала проверил на тестовом. Это спасло от лишних нервов: первая версия с ошибкой в выводе могла бы сломать вёрстку постов. Теперь у меня правило: любые изменения в коде сайта сначала проверяются на копии, а потом переносятся на прод. Для плагинов это особенно важно, потому что ошибка в плагине может уронить весь сайт разом.
И ещё одна деталь: не забывай про обновления. Мой маленький плагин работает уже долго, но я понимаю, что рано или поздно WordPress сменит API или выведет что-то из использованного устаревшим. Поэтому я стараюсь использовать только стабильные функции и периодически проверяю, нет ли предупреждений о депрекации. Маленький код — это легко поддерживать, и это ещё один плюс самописных решений.