Началось всё с того, что клиенту — кузовному цеху — понадобился сайт. Услуги, портфолио с фотографиями «до/после», статьи, отзывы, калькулятор. Стандартный набор. Я взял WordPress, установил несколько плагинов, настроил тему… и понял, что поддерживать этот зоопарк — ад.
Пять разных плагинов для CPT, два для SEO, один для форм, ещё один для шорткодов. Каждый со своими настройками, конфликтами стилей и непредсказуемым поведением при обновлении. Когда клиент попросил добавить поле «Время чтения» к статьям, а потом выяснилось, что плагин для CPT не дружит с плагином для SEO — я психанул и сел писать своё.
Принцип: всего один плагин
Первое правило, которое я для себя определил: один плагин заменяет все. Никаких «установите A, B и C, чтобы заработало». Активировал — и все CPT, поля, SEO, шорткоды уже на месте.
Второе правило: никакого кода в теме. Плагин не должен требовать правок functions.php. Он сам инжектит соцсети в хедер, контакты в футер, CSS-переменные в :root. Тема может быть любой — хоть стандартная Twenty Twenty-Four, хоть самописная.
Третье правило: при отключении сайт не падает. Для этого я сделал MU-плагин с полифиллами — заглушками для всех хелперов. Если клиент решит удалить AvtoService CPT, его сайт останется рабочим, просто без кастомных блоков.
Архитектура: модули, а не монолит
Плагин вырос до 15+ файлов в includes/. Каждый модуль вешает свои хуки самостоятельно, без централизованной функции-инициализатора. Это даёт гибкость: можно отключить ненужный модуль, просто убрав require из core.php, и ничего не сломается.
// core.php — просто список подключений require_once 'config.php'; require_once 'post-types.php'; require_once 'fields.php'; require_once 'templates.php'; require_once 'seo.php'; // ...
Никаких add_action('init', 'avtoservice_cpt_init'), внутри которых вызывается ещё десяток функций. Хуки вешаются прямо в файлах модулей — линейно, предсказуемо, без вложенности.
SEO без компромиссов
Стандартные SEO-плагины либо не видят мета-поля кастомных типов, либо требуют танцев с бубном. Я сделал свой SEO-модуль, который:
- Выводит метабокс с полями Title, Description, Keywords, OG Image для **всех** типов записей — CPT, страниц, постов
- Формирует OG-теги автоматически: заголовок из SEO Title, изображение из поля OG Image или из миниатюры
- Поддерживает SEO для архивов CPT и виртуальных страниц
- Не дублирует
<title>— переопределяет стандартный через фильтрdocument_title_parts
Отдельная гордость — виртуальные страницы. /about/, /contacts/, /calc/, /price/ — всё это работает без единой записи в БД, через rewrite rules и template_include. И для каждой можно задать свои SEO-настройки.
Настройки в одном месте
Раньше у клиента телефоны хранились в настройках темы, соцсети — в одном плагине, реквизиты — в другом, цвета — в кастомайзере. Я собрал всё в одну страницу: Настройки → AvtoService CPT.
Шесть вкладок на JavaScript, одна кнопка «Сохранить», все опции в wp_options с autoload = yes. Никакой мороки с перезагрузкой страницы при переключении вкладок.
Дизайн шаблонов: три итерации
Первая версия шаблона услуги была типичной: фоновое фото на всю ширину с затемнением, заголовок поверх, крошки, цена. Работало, но выглядело дёшево.
Вторая итерация — строгий корпоративный стиль. Чёрно-белая гамма, сухая типографика, никаких украшений. Клиент сказал: «Слишком сухо, у нас логотип красный».
Третья версия — «Премиум-сервис». Крупный заголовок, красные акценты, параметры в отдельной полосе под героем, чеклист с зелёными галочками, сайдбар с CTA. Заработало.
С портфолио было сложнее. Я перебрал четыре схемы: «журнальный разворот», «hero-карточка», «горизонтальная лента», «строгий паспорт». Остановились на «ленте»: фото во всю ширину, заголовок с параметрами сверху, миниатюры снизу. Чисто, линейно, глаз не прыгает.
Что получилось в итоге
Один плагин, который закрывает 90% потребностей кузовного автосервиса в сайте. Без зоопарка из сторонних решений, без привязки к теме, без падения при отключении.
Клиент доволен — сайт работает, заявки идут. Я доволен — код чище, чем после первой итерации. А самое приятное — плагин можно продать следующему такому же сервису, просто поменяв цвета и контент.