Перейти к содержимому
Эльдар Шахвалиев
Обсудить проект
← Все проекты
202606.2026 — presentВ работеполный цикл

Smartway — переезд сайта сервиса командировок на WordPress

B2B-сервис управления командировками (travel-tech SaaS) · Travel-tech / корпоративные командировки (business travel management, B2B SaaS)

Ведущий fullstack-разработчик WordPress (backend-фокус): аудит, адаптация темы, бэкенд, SEO, DevOps

Маркетинговый сайт из девяти лендингов жил на конструкторе — теперь тексты и картинки правит контент-менеджер, а страница вдвое легче лимита ТЗ.

  • PHP
  • JavaScript
  • HTML
  • CSS/SCSS
  • WordPress
  • классическая тема (Underscores _s)
  • SCF (Secure Custom Fields)
  • ACF Flexible Content
  • Gutenberg (ACF-блоки)
  • Contact Form 7
  • Flamingo
  • FluentSMTP
  • Yoast SEO (JSON-LD)
  • Redirection
  • IndexNow
  • WP Super Cache
  • MySQL
  • Splide
  • GLightbox
  • intl-tel-input
  • WebP/AVIF
  • Apache/Nginx
  • shared hosting (reg.ru)
  • WP-CLI
  • rsync
  • Git
  • Playwright
  • REST API
  • Composer/WPCS
41 → 14
активных плагинов после чистки (Фаза 2)
11 → 3
mu-plugins (удалён agent-bridge → закрыта дыра REST sw-agent/v1)
22
страницы статичной вёрстки dist перенесены в тему
58
ACF Flexible Content layout-ов в библиотеке (9 лендингов + главная + auth/legal, весь контент в админку)
366
ассетов фронта импортировано в медиатеку (SVG через safe-svg)
457
изображений сконвертировано в WebP (cwebp -q80, used-only)
19
записей client → case мигрировано + 301-редиректы /clients/* → /cases/* (D1)
10 → 6
дедупликация экспертов (CNT-03) с сохранением реального контента + 301 surname → full-name
≥2,3×
запас по KPI ТЗ: вес ≤526 КБ, JS ≤79 КБ, CSS ≤58 КБ gzip, CLS=0 (лимиты ТЗ: 1,2 МБ / 300 / 200 КБ)
37 → 19 мс
серверный TTFB кэш-хита после WPSC mod_rewrite + preload (6E)
2,23 ГБ + 127 МБ
ai1wm-бэкапы и осиротевший GeoIP вынесены из вебрута; uploads 332 → 206 МБ; −260 ревизий (6B)
10 находок (0×P0, 1×P1, 3×P2, 4×P3, 2×info)
QA-аудит Фазы 7 против dist (43 скриншота)
31 раздел / 40 скриншотов
HTML-руководство администратора (самодостаточное, офлайн)
11 правок / 7 кластеров
новая волна доработок заказчика — завершена и верифицирована
  • Пришёл новым подрядчиком после другой команды: начал с полного аудита, дальше вёл проект от вёрстки до сервера.
  • Собрал конструктор из 58 блоков, из которых редактор складывает страницы — без единой строчки кода.
  • Плагинов на сайте стало 14 вместо 41; из открытой части вынесено 2,23 ГБ архивов, закрыт служебный вход, через который сайтом можно было управлять снаружи.
  • Сделал поисковый фундамент переезда: адреса страниц, перенаправления со старых адресов, разметка для поисковиков, хлебные крошки и оглавления статей.
  • Написал руководство администратора на 31 раздел с 40 скриншотами — заказчик работает с сайтом сам.

Задача

Smartway — российский сервис, через который компании организуют командировки сотрудников: билеты, отели, такси, согласование поездок и отчётность. Маркетинговый сайт жил на конструкторе, и это упиралось в потолок: закрытый код нечем оптимизировать под поиск, а вес страниц и адреса разделов не в руках владельца.

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

Что сделано

  • Пришёл новым подрядчиком после другой команды и начал с полного разбора: что уже сделано, что сломано, что опасно. По итогам согласовал с заказчиком стратегию «адаптировать, не пересобирать» — чужой работающий код был сохранён, а не переписан заново.
  • Перенёс 22 страницы вёрстки на новый сайт один в один с исходным макетом и собрал конструктор из 58 блоков: теперь тексты, картинки и кнопки девяти лендингов и главной складываются в админке.
  • Навёл порядок в хозяйстве сайта: убрал лишние плагины, заменил нелицензионную копию платного расширения бесплатным аналогом с теми же возможностями, вынес архивы из открытой части и закрыл служебный вход снаружи.
  • Сделал поисковый фундамент переезда: понятные адреса страниц, перенаправления со старых адресов на новые, разметка данных о компании и статьях для поисковиков, хлебные крошки, оглавления статей.
  • Сдал работу с руководством администратора на 31 раздел с 40 скриншотами и отчётом заказчику — дальше сайт ведут без меня.

Итог

Было

  • Сайт на конструкторе; начатый другой командой перенос застрял на полпути, тексты лендингов вшиты в код
  • 41 плагин, нелицензионная копия платного расширения, архивы сайта скачиваются снаружи
  • Любая правка текста — через разработчика

Стало

  • Свой сайт: тексты и картинки девяти лендингов и главной правятся из админки
  • 14 плагинов, лицензионно чистые расширения, архивы убраны, служебный вход закрыт
  • Требования ТЗ по весу страницы выполнены с запасом больше чем вдвое

Плагинов на сайте стало 14 вместо 41, служебных расширений — 3 вместо 11; вместе с ними закрылась дыра, через которую сайтом можно было управлять снаружи. 2,23 ГБ архивов лежали в открытой части сайта и вынесены оттуда. Сервер отдаёт закэшированную страницу за 19 мс вместо 37. Страница укладывается в требования ТЗ с запасом больше чем вдвое: 526 КБ против лимита в 1,2 МБ. Сверка вёрстки с исходным макетом нашла 10 расхождений, ни одного критичного — все закрыты. Последняя волна доработок заказчика, 11 правок в 7 группах, завершена и проверена.

Переверстанный сайт сейчас работает на тестовом домене; выкат на боевой адрес — за заказчиком.

Технические детали

Решение и подход

Архитектура темы — классическая PHP-тема на Underscores (_s), сильно кастомизированная, на SCF. Ключевые инженерные решения:

  • Реестр бандлов route → bundle (inc/page-bundles.php + inc/enqueue.php): поэкранная загрузка CSS/JS, повторяющая исходные HTML 1:1 → выполнение требования ТЗ «JS по шаблонам, не глобально» и лимитов веса.
  • Гибрид-контент-модель (8B-2): библиотека ACF Flexible Content layout-ов с нулём fallback (контент только в БД), медиатека-пикер вместо путей, горизонтальные табы и группировка полей в редакторе — спроектировано под контент-команду без разработчика (источник: docs/tasks/phase8-8b2-pilot-taxi-plan.md, docs/progress.md).
  • SEO без костылей (8C): URL без слеша сделан через ядро (permalink_structure + redirect_canonical, 301 одним хопом), а не кастомным редиректором; schema — через фильтры Yoast wpseo_schema_*; переносимый inc/seo.php под гард WPSEO_VERSION.
  • Кэш под shared-хостинг reg.ru (без Redis/LiteSpeed): WP Super Cache на mod_rewrite; root-cause за nginx-прокси — детект HTTPS через X-Forwarded-Proto; security-заголовки в .htaccess (mod_headers), т.к. WPSC отдаёт кэш мимо PHP.
  • Безопасные миграции: client→case через swap post_type (слаги/мета 1:1) + структурный 301-хук в inc/rewrites.php (плагин Redirection не подхватывал первое regex-правило); удаления — через draft+rename (корзина на сервере отключена).

Стек и обоснование

Ядро. WordPress 7.0 с классической PHP-темой, а не FSE: бэкенд предыдущей команды был рабочим, и стратегия «адаптировать, не пересобирать» требовала совместимости с ним, а ТЗ — контроля над ЧПУ и шаблонами, который в блочной теме достаётся дороже.

SCF вместо nulled ACF Pro. Замена снимает юридический и security-риск разом, а миграция обошлась без экспорта: SCF сохраняет API, поэтому field groups, объявленные в PHP, переехали как есть.

Формы и почта. Contact Form 7 с conditional-fields и honeypot, Flamingo для журнала заявок, FluentSMTP для доставки — формы должны были повторять эталонную вёрстку строго 1:1, и CF7 давал это без переписывания разметки.

SEO и кэш. Yoast SEO — ради JSON-LD и шаблонов мета-тегов, схема расширяется через фильтры wpseo_schema_*. WP Super Cache вместо предписанного ТЗ LiteSpeed: на shared-хостинге reg.ru нет ни LiteSpeed, ни Redis, замена согласована с заказчиком.

Фронт. Эталонные HTML/CSS/JS и vanilla app.js из dist, к ним Splide (карусели), GLightbox (лайтбокс), intl-tel-input (маска телефона, подключён локально), self-hosted variable-шрифт Golos Text, изображения в WebP/AVIF через <picture>.

Инструменты. WP-CLI и rsync-деплой, git локально без remote, Composer с phpcs/WPCS, @wordpress/scripts для eslint/stylelint, Playwright для визуального QA и пиксельной сверки с эталоном.

Инженерные вызовы

  • Редактируемость «всего» без потери pixel-perfect — спроектирована библиотека из 58 переиспользуемых ACF Flexible Content layout-ов с вариантами hero/cta_form; ловушка: instructions ACF выводятся сырым HTML — незакрытые теги-примеры ломали DOM редактора (решено esc_html); top-level поля пер-страничных групп требуют префиксных name/уникальных key (иначе репитеры не читались).
  • Окружение reg.ru как данность: нет Redis/LiteSpeed, Apache за nginx-прокси — кэш и security-заголовки пришлось решать через mod_rewrite/mod_headers и X-Forwarded-Proto; статика отдаётся nginx-ом мимо .htaccess (заголовки на ассетах — тикет хостеру).
  • Yoast на staging: WP_ENVIRONMENT_TYPE=staging отключает canonical/indexables — потребовалась оговорка «на проде появится сам» + фильтр-гарантия /cases/.
  • Наследие предыдущей команды: обратный аудит дедупа экспертов (реальный контент был в «старых» записях, а не «новых»-заглушках); мёртвый плагин smartway-tilda-fallback с хардкод-путём прошлого автора; D1-миграция при отключённой корзине.
  • Регресс «пропала кнопка Обновить во всех Options» — ложно списан на роли 8E; реальная причина — display:none на колонке сабмита в admin-CSS (на SCF кнопка рендерится только в боковой колонке). Диагностика по view-source отделила клиентскую причину от серверной.
  • аудит
  • доработка существующего
  • миграция
  • разработка
  • деплой/DevOps
  • SEO
  • 152-ФЗ/ПДн (согласия)
  • производительность/CWV
  • контент-модель/редактируемость
  • документация
  • QA