Типы записей и таксономии WordPress: типичные ошибки
Тип записей зарегистрирован, а страница отдаёт 404. После смены темы каталог пропал из админки. Разбираем типичные ошибки с register_post_type и register_taxonomy и способы их избежать.

Вы зарегистрировали тип записей, добавили пару материалов, открыли адрес на сайте и получили 404. Или хуже: через полгода сменили тему, и каталог из двухсот позиций исчез из админки и с витрины. Данные целы, пропала только регистрация. Обе беды растут из одного места: register_post_type и register_taxonomy выглядят как простые вызовы, но связаны с правилами адресов, правами и редактором. Примеры рассчитаны на WordPress 6.x и PHP 7.4 и новее.
Где регистрировать: четыре подхода
Первый выбор делается ещё до кода, и исправлять его дороже всего.
| Подход | Что выигрываете | Чем платите |
|---|---|---|
| functions.php темы | Не нужно отдельных файлов | При смене темы тип исчезает из админки и с сайта, записи остаются в базе |
| Обычный плагин | Переживает смену темы, версионируется в git | Можно случайно отключить; сброс адресов нужно повесить на активацию |
| mu-plugin (wp-content/mu-plugins) | Грузится всегда, из админки не отключается | Хук активации не срабатывает, адреса сбрасываются вручную при выкладке |
| UI-плагин вроде Custom Post Type UI | Не нужен код | Настройки лежат в базе, их не видно в ревью, появляется зависимость от плагина |
Когда что выбирать
Критерий один: должен ли тип пережить смену темы. Если это данные сайта (каталог, объекты, кейсы), берите плагин или mu-plugin. Если тип нужен только шаблонам одной темы и вы готовы потерять его вместе с ней, хватит functions.php. UI-плагин оправдан, когда сайт ведёт человек без доступа к коду, а тип простой.
Рабочий каркас
Файл wp-content/plugins/portfolio-types/portfolio-types.php. Тип и таксономия регистрируются на хуке init, а адреса сбрасываются один раз при активации.
<?php
/**
* Plugin Name: Portfolio Types
* Version: 1.0.0
*/
// Для WordPress 6.x, PHP 7.4+
function pt_register_types() {
register_post_type( 'pt_portfolio', array(
'labels' => array(
'name' => 'Работы',
'singular_name' => 'Работа',
),
'public' => true,
'has_archive' => true,
'show_in_rest' => true,
'supports' => array( 'title', 'editor' ),
'rewrite' => array( 'slug' => 'portfolio' ),
) );
register_taxonomy( 'pt_work_type', array( 'pt_portfolio' ), array(
'labels' => array(
'name' => 'Типы работ',
'singular_name' => 'Тип работы',
),
'hierarchical' => true,
'show_in_rest' => true,
'rewrite' => array( 'slug' => 'work-type' ),
) );
}
add_action( 'init', 'pt_register_types' );
// Сброс правил адресов: один раз при активации, а не на каждом запросе
function pt_activate() {
pt_register_types();
flush_rewrite_rules();
}
register_activation_hook( __FILE__, 'pt_activate' );
function pt_deactivate() {
flush_rewrite_rules();
}
register_deactivation_hook( __FILE__, 'pt_deactivate' );
Проверка: после активации адрес /portfolio/ открывается архивом типа, а не 404.
Почему именно 404
Правила адресов* WordPress хранит в базе и сам их при появлении нового типа не пересобирает. Поэтому ставьте flush_rewrite_rules() на активацию. Если вызвать её внутри init, пересборка пойдёт на каждом запросе: это запись в базу и, на Apache, возможная перезапись .htaccess. Ручной способ: «Настройки → Постоянные ссылки → Сохранить» без изменений.
Что ломается
- Слишком длинное или занятое имя. Ключ типа записи не длиннее 20 знаков, ключ таксономии не длиннее 32, иначе функция вернёт
WP_Error, и тип не появится. Не берите имена ядра:post,page,attachment,revision,nav_menu_item, и не начинайте ключ сwp_. Свой префикс, какpt_в примере, снимает вопрос. - Нет show_in_rest. По умолчанию параметр выключен. Тип откроется в классическом редакторе, а у таксономии не будет панели в боковой колонке блочного редактора. Для самого поля редактора в
supportsнуженeditor. - public => true для служебных данных. Заявки и логи попадают в поиск по сайту, получают публичные адреса и (с WordPress 5.5) в стандартную карту сайта. Для внутренних типов ставьте
'public' => falseи'show_ui' => true, чтобы управлять ими из админки. - Свой capability_type. При значении
bookядро ждёт права вродеedit_books, а их нет ни у одной роли, включая администратора. Меню пропадает. Оставьте значение по умолчанию либо сразу выдайте права ролям и включитеmap_meta_cap. - Конфликт адресов. Архив типа и страница с одинаковым слагом борются за один адрес. Одинаковый
rewriteslug у типа и таксономии даёт 404 на одном из них. Разным сущностям давайте разные префиксы. - Переименование ключа в бою. Записи привязаны к строке с ключом типа, поэтому после смены ключа они «теряются».
Ключ типа записи — это адрес данных в базе, а не вывеска. Название в админке меняется когда угодно, ключ — только вместе с правкой таблиц.
Что делать дальше
Проверьте регистрацию без браузера: команды WP-CLI wp post-type list и wp taxonomy list покажут, что ядро видит ваши типы. Для mu-plugin и автоматических выкладок добавьте wp rewrite flush в скрипт деплоя. Затем откройте /wp-json/wp/v2/ и убедитесь, что маршруты типа есть в списке. Шаблоны single-{тип}.php и archive-{тип}.php — отдельная тема, здесь их не разбираем.
* Правила адресов (rewrite rules) — набор шаблонов, по которым WordPress превращает красивый адрес вроде /portfolio/my-work/ во внутренний запрос к базе. Хранятся в опции rewrite_rules и обновляются только при сбросе.
Аналитик звонков: Разбор записи звонка по этапам сделки: где сорвалось, что упущено, три исправляемые рекомендации с цитатами.
Спросить за 90 ₽Источники: WordPress Developer Resources: register_post_type(), WordPress Developer Resources: register_taxonomy()
Частые вопросы
Я пересохранил постоянные ссылки, а 404 остаётся. Что проверить?
Что, если у меня WordPress старше 5.0?
Можно ли переименовать ключ типа записи или таксономии, если контент уже есть?
Что будет с записями, если отключить плагин с типом?
Безопасно ли вызывать flush_rewrite_rules на проде?
Материал носит информационный характер и подготовлен редакцией «Агентуры». Он не является офертой, рекламой или индивидуальной консультацией. Упомянутые продукты, компании и торговые знаки принадлежат их правообладателям. Перед принятием решений, влекущих юридические или финансовые последствия, обратитесь к профильному специалисту.