Одиночная страница пользовательского типа записи перенаправляет на 404
Я объявил тип записи следующим образом:
$args = array(
'labels' => $labels,
'public' => true,
'publicly_queryable' => true,
'show_ui' => true,
'show_in_menu' => true,
'query_var' => true,
'rewrite' => array('slug' => 'agences'), // Устанавливает ярлык для типа записи
'capability_type' => 'post',
'has_archive' => true, // Включает архив для этого типа записи
'hierarchical' => false,
'menu_position' => 5,
'taxonomies' => array('brands', 'country'), // Прикрепленные таксономии
'supports' => array('title', 'editor', 'author', 'thumbnail', 'custom-fields') // Поддерживаемые поля
);
register_post_type('destinations', $args); // Регистрация типа записи 'destinations'
Изначально я мог получить доступ к одиночной странице этого типа записи, используя шаблон single-agences.php
, но теперь происходит перенаправление на 404.
Я проверил другие ответы и обнаружил, что это распространенная ошибка, но предложенные решения не помогли. Любая помощь будет замечательной.

Новый зарегистрированный CPT возвращает ошибку 404, потому что функция register_post_type()
не обновляет правила перезаписи URL. Поэтому вам решать, делать это вручную или автоматически.
Вручную:
Перейдите в /wp-admin/
, затем Настройки » Постоянные ссылки и просто нажмите кнопку Сохранить изменения, чтобы обновить правила перезаписи.
Автоматически:
Вы можете обновить правила перезаписи с помощью функции flush_rewrite_rules()
. Однако, поскольку register_post_type()
вызывается через хук init
, это будет происходить каждый раз при срабатывании хука. Кодекс также предупреждает:
Эта функция полезна при работе с пользовательскими типами записей, так как позволяет автоматически обновлять правила перезаписи WordPress (обычно это нужно делать вручную для новых CPT). Однако это ресурсоемкая операция, поэтому её следует использовать только в случае крайней необходимости.
Поэтому лучше привязать обновление правил к чему-то, что срабатывает один раз, и обновлять их только при необходимости. Как уже показал @cybmeta, можно использовать подход @bainternet:
/**
* Активация страницы CPT
* @author Bainternet
* @link http://en.bainternet.info/2011/custom-post-type-getting-404-on-permalinks
* ---
*/
$set = get_option( 'post_type_rules_flased_mycpt' );
if ( $set !== true ) {
flush_rewrite_rules( false );
update_option( 'post_type_rules_flased_mycpt', true );
}
Он сохраняет значение в таблицу options
только для вашего типа записи. Если значение отсутствует, он обновляет правила. Если оно есть — пропускает.
Обратите внимание, что этот метод делает запрос к базе данных каждый раз (если не закешировано). Я бы рекомендовал привязать код к хуку after_setup_theme
для темы или register_activation_hook
для плагина.
Бонус
При отладке правил перезаписи могут помочь такие плагины:

Это не вновь зарегистрированный CPT. Также я много раз пробовал сбрасывать правила перезаписи, но это не помогло. Когда я использую формат постоянных ссылок "plain", это работает. Но не с форматом "Post name".

Не могли бы вы подтвердить, что mod_rewrite
включен на вашем сервере и работает для других стандартных URL этой установки WordPress? Я бы также рекомендовал базовый процесс отладки.

На сервере у меня много установок WordPress с несколькими пользовательскими типами записей, и все работают нормально.

Тогда для нас это невозможно обнаружить. Вы можете поделиться своим продуктом через GitHub, Bitbucket, GitLab и т.д., чтобы кто-то мог проверить, работает ли это глобально или нет. Это слишком локализовано для вашей среды разработки, и, боюсь, никто не сможет это проверить. :(
