Перейти к основному содержимому

Разработка 23 октября 2026г. 9 мин чтения

WordPress в подкаталоге: зачем так делают и какой ценой

Наш сайт работает на WordPress, ядро которого лежит не в корне, а в отдельной подпапке: адрес сайта - корень домена, адрес движка и админки - подкаталог /wp/. Схема прижилась не случайно: она держит корень чистым и отделяет чужой код от своего. Расскажем, что она даёт и где после переезда приходится быть внимательнее.

Наш сайт работает на WordPress, ядро которого лежит не в корне, а в отдельной подпапке: адрес сайта - корень домена, адрес движка и админки - подкаталог /wp/. Схема прижилась не случайно: она держит корень чистым и отделяет чужой код от своего. Расскажем, что она даёт и где после переезда приходится быть внимательнее.

Обычно об этом не думают: движок ставят в корень, и файлы ядра лежат вперемешку с остальным содержимым сайта. Вопрос всплывает, когда рядом с CMS появляется что-то своё - обработчик форм, набор статичных инструментов, страницы, которые движок не должен видеть.

Как устроена эта схема

В обычной установке всё просто: WordPress разворачивается в корень сайта, index.php лежит там же, где wp-admin, wp-includes и тема. Адрес сайта и адрес движка совпадают - оба указывают на корень домена.

При переносе в подкаталог ядро переезжает в отдельную папку, например /wp/: там wp-admin, wp-includes, часть wp-content. В корне остаётся один файл - index.php, который подключает движок из подпапки и запускает весь процесс.

В настройках WordPress различают два адреса. Первый - адрес WordPress, siteurl - указывает на подпапку с ядром, туда же ведёт вход в админку. Второй - адрес сайта, home - указывает на корень домена, его видит посетитель в адресной строке. Витрина открывается по короткому адресу, всё системное - по адресу с подкаталогом.

Обычная установка Движок в подкаталоге
index.php в корне, полная копия ядра в корне, одна строка подключения
Админка /wp-admin/ /wp/wp-admin/
siteurl и home совпадают различаются
Файлы в корне только WordPress движок и свой код рядом

Зачем переносить движок из корня

Главный довод - чистота корня. Когда в проекте, кроме самого движка, живёт что-то своё - обработчики форм, отдельные инструменты, статические страницы, - удобно сразу видеть, где чужой код, а где свой, а не искать нужный файл среди полусотни папок ядра.

Ядро время от времени обновляется целиком. Когда оно лежит в отдельной папке, замена файлов не задевает ничего постороннего. На обычной установке та же операция идёт в куче, где легко случайно перезаписать что-то своё.

Есть и слабый эффект безопасности: боты массово сканируют стандартные адреса /wp-admin/ и /wp-login.php прямо в корне. Когда админка открывается по нестандартному пути с подкаталогом, часть автоматических атак просто не находит цель. Это не замена нормальной защите - паролям, обновлениям, ограничению попыток входа, - а дополнительный слой поверх неё. Базовые правила разбирали в статье про защиту сайта от взлома.

Установка с нуля против перевода готового сайта

Настроить новый сайт по этой схеме проще, чем кажется. WordPress скачивается не в корень, а в подпапку, а в корень домена копируются два файла - index.php и .htaccess - с изменённым путём подключения к ядру. Дальше в настройках задаются два разных адреса: siteurl с подкаталогом и home без него.

Перевод уже работающего сайта сложнее: снять бэкап файлов и базы, перенести системные папки ядра в новую подпапку, поправить оба адреса в базе - через таблицу настроек или константами в конфиге, - переписать корневой index.php под новый путь и проверить правила в .htaccess. Дальше пересохранить постоянные ссылки и пройти по каждому типу страниц, прежде чем считать перенос законченным.

Что проверить сразу после переключения

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

Карта сайта и robots.txt. Часть SEO-плагинов строит адрес карты сайта от siteurl - адреса движка. Файл может отдаваться из подкаталога, а робот будет искать его в корне и не находить. То же с виртуальным robots.txt, который тоже норовит уехать в подпапку. Правила для обоих файлов разбирали в статье про sitemap.xml и robots.txt.

Пути к загрузкам. Если в базе остались абсолютные ссылки на старую структуру, картинки и документы из медиатеки ссылаются на несуществующий адрес. Проверяется просто: открыть пару старых постов и посмотреть, откуда реально грузятся изображения.

Письма со ссылками на админку. Уведомления о заказах, сброс пароля, системные письма плагинов интернет-магазина иногда собирают ссылку из siteurl. Это нормально - вход и должен вести в подкаталог, - но пользователей и коллег стоит один раз предупредить, чтобы ссылка с /wp/ в адресе не выглядела ошибкой.

Где спотыкаются плагины

Не каждый плагин аккуратно различает два адреса. Часть из них при формировании ссылок, изображений в письмах, иконки сайта или виджетов берёт siteurl - адрес движка - там, где по смыслу должен быть home - адрес сайта. В результате отдельные ссылки на витрине незаметно ведут в подкаталог вместо корня.

Ловится это точечно: после установки или обновления плагина стоит открыть исходный код нескольких страниц и поискать подкаталог движка там, где его быть не должно - в ссылках меню, в адресах картинок, в структурированных данных. Ставить сразу пачку плагинов и потом разбираться, какой из них сломал что, не стоит - проверка по одному экономит время на диагностике. Разбор, какие плагины на что способны, - в статье про плагины WordPress.

Перенос на другой хостинг и сериализованные данные

Здесь у схемы с подкаталогом есть отдельная ловушка. WordPress хранит часть настроек - виджеты, параметры некоторых плагинов, метаданные записей - в сериализованном формате PHP, где перед каждой строкой стоит число, равное её длине в байтах.

Обычный SQL-запрос "найти старый адрес, заменить на новый" меняет саму строку, но не пересчитывает число перед ней. Если новый адрес по длине отличается от старого хотя бы на один символ, движок не может разобрать значение при чтении, и настройка молча теряется - без ошибки, без предупреждения: виджет в сайдбаре вдруг оказывается пустым.

При обычной установке для замены нужен один адрес. При схеме с подкаталогом их минимум два - siteurl и home, - и на новом хостинге структура не всегда сохраняется: подкаталог то остаётся тем же, то переименовывается заодно с переездом. Логика "два адреса - вдвое внимательнее" здесь не работает: риск ошибки при ручной замене от этого только растёт.

Правильный путь - замена инструментом, который умеет пересчитывать длину сериализованных строк, например встроенной командой WP-CLI, а не ручным UPDATE в таблицах. Порядок действий для переезда целиком - в статье про перенос WordPress на другой хостинг; требования к новой площадке стоит свериться заранее - в статье про выбор хостинга для WordPress.

Когда эта схема не нужна

Для сайта на пять статичных страниц без частых обновлений плагинов и без своего кода рядом с движком вся эта возня не окупается. Лишний адрес в настройках, необходимость объяснять новому человеку в проекте, почему админка не там, где он привык, - цена за преимущество, которому негде проявиться.

Схема оправдана там, где вместе с CMS в корне живёт что-то ещё: собственные скрипты, статические инструменты, отдельные разделы сайта, которые движок не должен обслуживать напрямую. У нас в проекте это именно так: рядом с ядром в корне лежат свои обработчики и статичные страницы, и разделение по папкам снимает путаницу, а не создаёт её.

Чек-лист перед переключением на подкаталог

  • Снят и проверен на восстановление полный бэкап файлов и базы.
  • В настройках заданы оба адреса - siteurl с подкаталогом и home без него, - и разница между ними осознанная, а не случайная.
  • Постоянные ссылки пересохранены и проверены на выборке страниц разных типов.
  • Карта сайта и robots.txt отдаются по ожидаемому адресу в корне, а не из подкаталога.
  • Пути к загруженным файлам проверены на нескольких старых записях.
  • Ключевые плагины проверены по одному, а не пачкой, на предмет "уехавших" ссылок.
  • Если следом планируется переезд на другой хостинг, замена адресов в базе выполняется инструментом с пересчётом сериализации, а не ручным SQL-запросом.

Чистый корень против лишнего адреса

Схема с движком в подкаталоге - не универсальное правило, а размен: порядок в файлах и барьер для ботов в обмен на два адреса вместо одного и внимательность к плагинам и переездам. Для проекта, где рядом с CMS живёт что-то своё, размен того стоит. Для простого сайта из нескольких страниц - нет, там выигрывать особо не от чего.

Если разбираетесь, стоит ли переносить движок в подпапку на своём проекте, или планируете новый сайт с прицелом на такую структуру с самого начала, вопрос стоит обсуждать на этапе технического задания, а не после переезда. В тарифах видно, во что укладывается разработка и перенос сайта при разных объёмах работ.

Частые вопросы

Зачем вообще держать WordPress не в корне сайта?

Чтобы отделить файлы ядра от своих: скриптов, статики, других разделов сайта. Корень остаётся чистым, обновление движка не рискует задеть чужой код, а админка открывается по нестандартному адресу, что отсекает часть автоматических атак на wp-admin.

Можно ли перевести уже работающий сайт на такую схему, или это только для новых проектов?

Можно, но перенос сложнее установки с нуля: нужно переместить файлы ядра, поменять два адреса в базе, переписать корневой index.php и .htaccess, пересохранить постоянные ссылки и проверить все типы страниц. Без бэкапа такую операцию лучше не начинать.

Почему после переноса иногда ломаются ссылки в письмах или в карте сайта?

Часть плагинов строит адреса от siteurl - адреса движка, а не от home - адреса сайта. Если плагин не различает эти два поля, ссылка в письме, в sitemap или в favicon может увести пользователя в подпапку вместо корня. Это лечится точечно, плагин за плагином.

Правда ли, что при переезде на другой хостинг такую схему легко сломать?

Да, если менять адреса в базе обычным SQL-запросом "найти и заменить". WordPress хранит часть настроек в сериализованном формате, где перед строкой стоит её длина, и после замены длина не совпадает - настройка не читается. Нужен инструмент, который пересчитывает длину, например WP-CLI.

Нужен сайт по этой теме?

Расскажите о задаче – вернёмся с расчётом и предложением структуры.