Как полностью отключить архив таксономии на фронтенде?
Я зарегистрировал три пользовательские таксономии. Все три таксономии прикреплены к моему пользовательскому типу записи.
Есть только одна таксономия из трех зарегистрированных, к которой я хотел бы полностью закрыть доступ на фронтенде сайта.
Какое решение будет наилучшим?
Я экспериментировал с различными аргументами при регистрации таксономии, но ничего не работает.
$args['show_in_nav_menus'] = false;
$args['query_var'] = false;
$args['public'] = false;
Может стоит просто использовать хук template_redirect
и сделать проверку is_tax()
? Если это та таксономия, которую я хочу отключить, просто сделать перенаправление на архив пользовательского типа записи?

Ответ s_ha_dum не сработал для меня, но вот что помогло:
/**
* Полностью отключает архивы терминов для указанной таксономии.
* @param string $taxonomy Название таксономии WordPress
*/
function kill_taxonomy_archive($taxonomy){
add_action('pre_get_posts', function($qry) {
if (is_admin()) return;
if (is_tax($taxonomy)){
$qry->set_404();
}
}
);
}

+1 — Это более "по-вордпрессовски", чем принятый ответ. В идеале должен быть аргумент "has_archive", как у типов записей...

Это вызывает уведомление Undefined variable: taxonomy in ... [location]
. Можно ли этого избежать?

Таксономии WordPress предоставляют гибкость в настройке их свойств при регистрации. Чтобы отключить архивы таксономий в WordPress, установите параметр "public" в значение "false", как показано в примере кода ниже. Это удалит ссылку "Просмотр" из интерфейса таксономии и перенаправит пользователя на главную страницу сайта при попытке вручную перейти по URL таксономии.
Пример
// Регистрация пользовательской таксономии
function custom_taxonomy() {
$labels = array(
'name' => _x( 'Таксономии', 'Общее название таксономии', 'text_domain' ),
'singular_name' => _x( 'Таксономия', 'Уникальное название таксономии', 'text_domain' ),
'menu_name' => __( 'Таксономия', 'text_domain' ),
'all_items' => __( 'Все элементы', 'text_domain' ),
'parent_item' => __( 'Родительский элемент', 'text_domain' ),
'parent_item_colon' => __( 'Родительский элемент:', 'text_domain' ),
'new_item_name' => __( 'Название нового элемента', 'text_domain' ),
'add_new_item' => __( 'Добавить новый элемент', 'text_domain' ),
'edit_item' => __( 'Редактировать элемент', 'text_domain' ),
'update_item' => __( 'Обновить элемент', 'text_domain' ),
'view_item' => __( 'Просмотреть элемент', 'text_domain' ),
'separate_items_with_commas' => __( 'Разделяйте элементы запятыми', 'text_domain' ),
'add_or_remove_items' => __( 'Добавить или удалить элементы', 'text_domain' ),
'choose_from_most_used' => __( 'Выбрать из наиболее используемых', 'text_domain' ),
'popular_items' => __( 'Популярные элементы', 'text_domain' ),
'search_items' => __( 'Поиск элементов', 'text_domain' ),
'not_found' => __( 'Не найдено', 'text_domain' ),
'no_terms' => __( 'Нет элементов', 'text_domain' ),
'items_list' => __( 'Список элементов', 'text_domain' ),
'items_list_navigation' => __( 'Навигация по списку элементов', 'text_domain' ),
);
$args = array(
'labels' => $labels,
'hierarchical' => false,
'public' => false, // Установите false, чтобы удалить ссылку "Просмотр" из админки и перенаправлять на главную при переходе по ссылке таксономии.
'show_ui' => true,
'show_admin_column' => true,
'show_in_nav_menus' => true,
'show_tagcloud' => true,
);

Это единственно правильный ответ. Для тех, кто хочет фильтровать существующие таксономии, можно использовать фильтр register_taxonomy_args
.

Вместо public = false добавьте другую переменную в массив publicly_queryable = false, что скроет опцию просмотра, а public= false полностью удалит опцию из меню в админ-панели.

Я не уверен, почему @chris-herbert написал это именно так, но если добавить этот код в файл функций, это приведёт к принудительному перенаправлению любой навигации на этот архив на страницу 404.
add_action('pre_get_posts', 'kill_taxonomy_archive');
function kill_taxonomy_archive($qry) {
if (is_admin()) return;
if (is_tax('tax-slug')){
$qry->set_404();
}
}

Чтобы гарантировать, что ваша таксономия никогда не будет запрашиваться на фронтенде, вы можете исключить её из всех фронтенд-запросов.
add_action(
'pre_get_posts',
function($qry) {
if (is_admin()) return;
$kill = 'genre'; // исключить эту таксономию
$tax_query = $qry->get('tax_query');
if (empty($tax_query)) return;
$relation = false;
if (isset($tax_query['relation'])) {
$relation = $tax_query['relation'];
unset($tax_query['relation']);
}
foreach ($tax_query as $k => &$tax) {
if (isset($tax['taxonomy']) && 'genre' === $tax['taxonomy']) {
unset($tax_query[$k]);
}
}
if (1 < count($tax_query)) {
$tax_query['relation'] = $relation;
}
$qry->set('tax_query',$tax_query);
}
);
Использование замыкания (closure) делает этот callback трудным для удаления.
Вы также можете реализовать редирект, как вы предполагали, но это не предотвратит вторичные запросы в шаблонах страниц или виджетах от получения таксономии или может вызвать проблемы, если попытаетесь выполнить редирект на поздних этапах загрузки страницы.

Я проголосовал против, чтобы отговорить людей использовать этот хакерский приём. Смотрите ответ @chris-herbert ниже, который больше соответствует подходу WordPress (хотя и не идеален, но это вина WP).
