Как отключить один вид для пользовательского типа сообщения?

47

Я создал собственный тип записи:

register_post_type('sample_post_type',array(
    'labels' => array(
        'name' => _x('Sample Posts', 'post type general name'),
        'singular_name' => _x('Sample Post', 'post type singular name')
    ),
    'public' => true,
    'show_in_nav_menus' => false,
    'exclude_from_search' => true
));

Как я могу отключить просмотр одного сообщения для этого конкретного типа сообщения? Отображение простого 404 - это нормально, или перенаправление на домашнюю страницу. Это внутри плагина, поэтому я не могу создать файл single-sample_post_type.php для настройки пустой страницы.

passatgt
источник

Ответы:

43

Вы можете использовать template_redirectловушку для перенаправления для пользовательского типа записи, вы можете использовать любой другой URL-адрес, который вы хотите использовать вместо home_url()кода ошибки в другом аргументе.

<?php
add_action( 'template_redirect', 'wpse_128636_redirect_post' );

function wpse_128636_redirect_post() {
  $queried_post_type = get_query_var('post_type');
  if ( is_single() && 'sample_post_type' ==  $queried_post_type ) {
    wp_redirect( home_url(), 301 );
    exit;
  }
}
?>

Обновлено:

Альтернативным подходом было бы установить:

'publicly_queryable'  => false`

при регистрации пользовательского поста, упомянутого @gustavo ранее. Но он просто полностью удаляет страницу и перенаправляет вас на страницу 404. Кроме того, он скрывает как отдельную страницу, так и страницу архива, в основном полностью скрыт от внешнего интерфейса и может быть установлен только для пользовательских сообщений.

^ Этот подход работает, если вы хотите зарегистрировать пользовательский пост только для администратора / внутреннего использования.

Кумар
источник
Хорошее решение Я обнаружил, что было полезно выполнить это перенаправление только для неаутентифицированных пользователей, проверив, get_current_user_id()оценивает ли оно значение 0.
RevNoah
2
Пожалуйста, проверьте форму ответа @Gustavo
Ричард
2
почему бы не использовать только is_singular('post-type-slug')в if()условии вместо 2 условий?
Акаш К.
@AkashK. Да, это может сработать, не знал о функции.
Кумар
75

Просто установить аргумент

'publicly_queryable'  => false

когда вы вызываете register_post_type ()

Gustavo
источник
1
Это похоже на ответ, чтобы помешать вашему CPT создавать реальные веб-страницы, в то же время создавая все ссылки на базы данных.
Бен Расикот
27
Это тоже скрывает архив
космонавт
1
Это должен быть принятый ответ.
SinisterBeard
Для меня это вызывает перенаправление на домашнюю страницу вместо 404. Есть идеи почему? Я регистрирую post_type в Piklist, на случай, если это актуально.
emersonthis
8

Более простой способ сделать это - передать следующие аргументы при регистрации пользовательского типа сообщения.

register_post_type('sample_post_type',array(
'labels' => array(
    'name' => _x('Sample Posts', 'post type general name'),
    'singular_name' => _x('Sample Post', 'post type singular name')
),
'public' => true,
'exclude_from_search' => true,
'show_in_admin_bar'   => false,
'show_in_nav_menus'   => false,
'publicly_queryable'  => false,
'query_var'           => false
));
0v3rth3d4wn
источник
1
На самом деле вам нужно publically_querableбыть правдой, чтобы архивы почтовых типов работали.
Howdy_McGee
Это не работает для меня. Он просто перенаправляет обратно на домашнюю страницу при попытке зайти в архив
Яхья Уддин
7

Один. Из вашего файла функций.

add_action( 'template_redirect', 'redirect_cpt_singular_posts' );
    function redirect_cpt_singular_posts() {
      if ( is_singular('your-cpt-slug') ) {
        wp_redirect( home_url(), 302 );
        exit;
      }
    }

Два. Из вашего файла single.cpt.php:

<?php wp_redirect( home_url() ); exit; ?>
Брэд Далтон
источник
Мне понравился второй вариант. Но мне нужно знать, есть ли недостаток с этим вторым вариантом.
user2584538
@ user2584538 Если у вас нет собственного single-cpt_name.phpфайла, вы не сможете это сделать. Если вы поместите функцию в простой файл плагина, вы можете активировать / деактивировать без редактирования какого-либо файла.
EliasNS
2

Исходя из действительно хорошего ответа Свена, я переписал его функцию, чтобы упростить добавление нескольких типов записей, используя in_array()оператор if, а затем перенаправлять на страницу архива вместо домашней страницы.

(кстати, я думаю, что установка query_varи / или publically_queryableзначение false отключит не только отдельные представления, но и собственное представление архива, переопределяя 'has_archive' => true. В этом случае вы все равно можете настроить собственный WP_query и создать свою собственную страницу архива, в шаблон, но основной запрос больше этого не сделает, не так ли?)

function fq_disable_single_cpt_views() {
  $queried_post_type = get_query_var('post_type');
  $cpts_without_single_views = array( 'my-post-type', 'my-other-post-type' );
  if ( is_single() && in_array( $queried_post_type, $cpts_without_single_views )  ) {
    wp_redirect( home_url( '/' . $queried_post_type . '/' ), 301 );
    exit;
  }
}

add_action( 'template_redirect', 'fq_disable_single_cpt_views' );
slashbob
источник
2

Протестировано все перечисленные выше, и реальное решение проще, чем любые предлагаемые перенаправления.

Для того, чтобы архив был доступен и перечислял элементы, а один пост не был доступен и автоматическое перенаправление на набор 404

'query_var' => false

при регистрации вашего CPT. Если вы установите publicly_queryableзначение false, ваши архивы будут перенаправлены на дом, любая другая комбинация не будет работать. Установите в query_varfalse, и это все.

Вот полный CPT https://gist.github.com/danyj/bfd038d3c8d578548c4d700bd0a7942a

см. строку 50 https://gist.github.com/danyj/bfd038d3c8d578548c4d700bd0a7942a#file-thz_cpt_items_single_view_redirect-php-L50

как указано здесь

https://codex.wordpress.org/Function_Reference/register_post_type

Примечание. Если query_var пуст, равен null или имеет логическое значение FALSE, WordPress по-прежнему будет пытаться его интерпретировать (4.2.2), а предварительный просмотр / просмотр пользовательского сообщения вернет значение 404.

Бенн
источник
Это похоже на взлом, но, похоже, работает. Хотелось бы, чтобы они просто добавили выделенное свойство has_single вместе с существующим свойством has_archive.
PowerBoy
0

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

Установка publicly_queryableдля falseили rewriteв falseпомешает для отображения как одного и архивного вида. В register_post_typeаргументах функции нет флага, предотвращающего создание только правил перезаписи одного представления.

https://github.com/WordPress/WordPress/blob/5.2.3/wp-includes/class-wp-post-type.php#L540

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

/**
 * Register event post type
 */
function wpse_128636_register_event_post_type() {

    $labels = array(
        'name' => __( 'Events' ),
        'singular_name' => __( 'Event' ),
        'add_new' => __( 'Add new' ),
        'add_new_item' => __( 'Add new' ),
        'edit_item' => __( 'Edit' ),
        'new_item' => __( 'New' ),
        'view_item' => __( 'View' ),
        'search_items' => __( 'Search' ),
        'not_found' => __( 'Not found' ),
        'not_found_in_trash' => __( 'Not found Events in trash' ),
        'parent_item_colon' => __( 'Parent' ),
        'menu_name' => __( 'Events' ),

    );

    $args = array(
        'labels' => $labels,
        'hierarchical' => false,
        'supports' => array( 'title', 'page-attributes' ),
        'public' => true,
        'show_ui' => true,
        'show_in_menu' => true,
        'show_in_nav_menus' => true,
        'publicly_queryable' => true,
        'exclude_from_search' => true,
        'has_archive' => true,
        'rewrite' => array('slug' => 'event'),
        'capability_type' => 'post',
    );

    register_post_type( 'event', $args );
    remove_rewrite_tag( '%event%' ); // This line will remove event rewrite rules for single view
}

add_action( 'init', 'wpse_128636_register_event_post_type' );

Еще одним бонусом является то, что теперь вы можете создавать простые страницы WordPress, используя структуру постоянных ссылок типа события ( event/simple-page), которая может быть полезна на сложных веб-сайтах.

Не забудьте сбросить правила перезаписи после модификации кода.

kierzniak
источник