¿Cómo deshabilitar la vista individual para un tipo de entrada personalizada?

5 ene 2014, 16:05:33
Vistas: 126K
Votos: 75

Dado este tipo de entrada personalizada:

register_post_type(
    'sample_post_type',
    [
        'labels' => [
            'name' => _x('Entradas de Ejemplo', 'nombre general del tipo de entrada'),
            'singular_name' => _x('Entrada de Ejemplo', 'nombre singular del tipo de entrada'),
        ],
        'public' => true,
        'show_in_nav_menus' => false,
        'exclude_from_search' => true,
    ]
);

¿Cómo puedo deshabilitar la vista de entrada individual para este tipo de entrada en particular? Mostrar un simple 404 está bien, o redirigir a la página de inicio. Como esto es un plugin, no puedo crear un archivo single-sample_post_type.php para configurar una página vacía.

0
Todas las respuestas a la pregunta 9
4
107

Solo establece el argumento

'publicly_queryable'  => false

cuando llamas a register_post_type()

27 dic 2014 23:38:13
Comentarios

Esto parece la respuesta para evitar que tu CPT cree páginas web reales mientras sigue creando todas las referencias en la base de datos.

Ben Racicot Ben Racicot
17 sept 2015 21:11:49

Esto también oculta el archivo

spaceman spaceman
11 oct 2016 19:12:19

Esta debería ser la respuesta aceptada.

SinisterBeard SinisterBeard
16 mar 2018 12:26:45

Para mí esto causa una redirección a la página de inicio en lugar de un error 404. ¿Alguna idea de por qué? Estoy registrando el post_type con Piklist, por si eso es relevante.

emersonthis emersonthis
10 sept 2018 00:27:17
6
86

Para deshabilitar la vista individual de un CPT (Tipo de Entrada Personalizado) puedes redirigir a los usuarios a una URL específica o deshabilitarla durante el registro del propio CPT.

MÉTODO 1:

Redirigir la vista individual del CPT a una URL personalizada, mientras la página de archivo permanece accesible públicamente.

Puedes usar el hook template_redirect para redirigir al usuario. Puedes usar cualquier URL en lugar de home_url() y el código de error deseado como segundo argumento.

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

function wpse_128636_redirect_post() {
  if ( is_singular( 'sample_post_type' ) ) :
    wp_redirect( home_url(), 301 );
    exit;
  endif;
}
?>

MÉTODO 2:

Deshabilitar completamente las páginas individuales y de archivo desde el front-end; Funciona solo para Tipos de Entradas Personalizados.

Un enfoque alternativo es establecer publicly_queryable en false al registrar la entrada personalizada.

'publicly_queryable'  => false

Esto oculta tanto la página individual como la de archivo para el CPT, y solo puede usarse para entradas personalizadas.

Aunque el archivo y la vista individual estén ocultos, aún puedes agregar una plantilla de página o un bloque personalizado para listar las entradas si es necesario.

5 ene 2014 16:12:14
Comentarios

Una buena solución. Encontré que fue útil realizar esta redirección solo para usuarios no autenticados, verificando si get_current_user_id() devuelve 0.

RevNoah RevNoah
29 jun 2015 16:25:32

Por favor revisa la respuesta de @Gustavo

Richard Richard
18 nov 2016 11:17:44

¿por qué no usar solo is_singular('post-type-slug') en la condición if() en lugar de 2 condiciones?

Akash K. Akash K.
22 oct 2018 23:36:19

@AkashK. Sí, eso también podría funcionar, no estaba al tanto de esa función.

Kumar Kumar
23 oct 2018 09:26:50

la sugerencia remove_rewrite_tag( '%post-type-slug%' ); es una buena solución

Pbearne Pbearne
5 may 2020 01:20:44

Falta el corchete de cierre en el código - debería ser...

if ( is_singular( 'sample_post_type' ) )

neilgee neilgee
18 ago 2020 07:31:26
Mostrar los 1 comentarios restantes
6
17

Probé todas las soluciones mencionadas anteriormente y la solución real es más simple que cualquier redirección sugerida.

Para que el archivo sea accesible y liste los elementos, y que las entradas individuales no sean accesibles y redirijan automáticamente a un error 404, configura:

'query_var' => false

al registrar tu CPT (Tipo de Contenido Personalizado). Si configuras publicly_queryable como false, tus archivos serán redirigidos a la página de inicio; ninguna otra combinación funcionará. Simplemente establece query_var como false y eso es todo.

Aquí está el CPT completo: https://gist.github.com/danyj/bfd038d3c8d578548c4d700bd0a7942a

ver línea 50 https://gist.github.com/danyj/bfd038d3c8d578548c4d700bd0a7942a#file-thz_cpt_items_single_view_redirect-php-L50

como se indica aquí:

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

Nota: Si query_var está vacío, es null o un booleano FALSE, WordPress intentará interpretarlo (4.2.2) y las vistas previas/visualizaciones de tu contenido personalizado devolverán errores 404.

17 nov 2018 00:22:57
Comentarios

Se siente un poco como un truco pero parece funcionar. Ojalá agregaran una propiedad dedicada has_single junto con la propiedad existente has_archive.

powerbuoy powerbuoy
31 ene 2019 15:40:15

Hola, intenté hacer lo mismo pero no funcionó. A pesar de agregar el query_var a false, todavía puedo visitar los enlaces de páginas individuales. ¿Puedes ayudarme?

iSaumya iSaumya
13 oct 2020 15:08:30

@iSaumya intenta actualizar tus permalinks (ve a la página de permalinks y guarda nuevamente) o usa el comando wp-cli wp rewrite flush && wp cache flush

thetwopct thetwopct
28 may 2021 19:23:36

Ya no funciona (agosto 2022). La nota sobre que las vistas individuales fueron eliminadas tampoco existe más en la documentación.

Blorf Blorf
30 ago 2022 18:02:34

@blorf la nota todavía está en los documentos - está listada bajo publicly_queryable

rtpHarry rtpHarry
11 sept 2022 15:54:33

Esto funciona para mí, tengo Elementor con JetEngine y estoy configurando el tipo de publicación con public, publicly_queryable y has_archive establecidos en true, con query_var establecido en false. Mis archivos están funcionando y mis entradas individuales hacen 301 a la página de inicio.

rtpHarry rtpHarry
11 sept 2022 15:59:56
Mostrar los 1 comentarios restantes
3
10

Una forma más sencilla de hacerlo puede ser pasando los siguientes argumentos al registrar el Custom Post Type

register_post_type('sample_post_type',array(
'labels' => array(
    'name' => _x('Publicaciones de Ejemplo', 'nombre general del tipo de post'),
    'singular_name' => _x('Publicación de Ejemplo', 'nombre singular del tipo de post')
),
'public' => true,
'exclude_from_search' => true,
'show_in_admin_bar'   => false,
'show_in_nav_menus'   => false,
'publicly_queryable'  => false,
'query_var'           => false
));
24 may 2014 22:01:04
Comentarios

En realidad necesitarías que publically_querable sea verdadero para que funcionen los Archivos de Tipo de Entrada.

Howdy_McGee Howdy_McGee
12 nov 2014 21:42:28

Esto no funciona para mí. Simplemente redirige de vuelta a la página de inicio cuando intento acceder al archivo

Yahya Uddin Yahya Uddin
15 jul 2015 18:51:10

Establecer query_var como falso solo deshabilita el uso de variables de consulta en la URL, es decir /?sample_post_type=sample_slug, pero no impide acceder a través de /sample_post_type/sample_slug/

Enchiridion Enchiridion
5 ene 2021 07:57:12
3

Uno. Desde tu archivo de funciones.

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;
      }
    }

Dos. Desde tu archivo single.cpt.php:

<?php wp_redirect( home_url() ); exit; ?>
24 may 2014 22:10:43
Comentarios

Me gustó la segunda opción. Pero necesito saber si hay alguna desventaja con esta segunda opción.

user2584538 user2584538
10 oct 2017 09:27:08

@user2584538 Si no tienes un archivo personalizado single-cpt_name.php no podrías hacerlo. Si pones la función en un archivo simple de plugin, podrías activar/desactivar sin editar ningún archivo.

Elías Gómez Elías Gómez
5 feb 2018 12:12:42

La desventaja probablemente sería en cuanto a SEO. Para cualquiera de esas respuestas. Recomendaría agregar la siguiente meta etiqueta <meta name="robots" content="none, nosnippet, noarchive" /> en cada página que decidas redirigir.

amarinediary amarinediary
2 ene 2021 04:12:57
3

Trabajando a partir de la muy buena respuesta de Sven, reescribí su función para facilitar la adición de múltiples tipos de publicación utilizando in_array() en la declaración if y luego redirigiendo a la página de archivo en lugar de a la página de inicio.

(por cierto, creo que la configuración query_var y/o publically_queryable en false deshabilitará no solo las vistas individuales, sino también la vista de archivo nativa, anulando 'has_archive' => true. En ese caso, aún puedes configurar un WP_query personalizado y crear tu propia página de archivo, en una plantilla, pero la consulta principal ya no lo hará, ¿verdad?)

function fq_disable_single_cpt_views() {
  $queried_post_type = get_query_var('post_type');
  $cpts_without_single_views = array( 'mi-tipo-de-publicacion', 'mi-otro-tipo-de-publicacion' );
  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' );
9 jul 2016 19:27:21
Comentarios

esta fue una buena idea, pero no funciona si cambias tu redirección para los CPTs

rudtek rudtek
23 mar 2020 19:57:53

Cambié tu línea wp_redirect a wp_redirect( get_post_type_archive_link( $queried_post_type ), 301 ); ¡funciona perfectamente!

rudtek rudtek
23 mar 2020 20:06:25

Bien. Buena mejora.

slashbob slashbob
24 mar 2020 23:18:25
2

En caso de que desees deshabilitar completamente la vista individual de un tipo de publicación personalizado en el frontend pero aún así poder mostrar la página de archivo, las cosas se complican un poco.

Establecer publicly_queryable en false o rewrite en false evitará que se muestren tanto la vista individual como la de archivo. No hay una bandera en los argumentos de la función register_post_type para prevenir la creación de reglas de reescritura solo para la vista individual.

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

Sin embargo, puedes eliminar la etiqueta de reescritura después de registrar tu tipo de publicación y esto dejará intactas las reglas de reescritura de la vista de archivo, pero eliminará solo las reglas de reescritura de la vista individual.

/**
 * Registrar el tipo de publicación 'event'
 */
function wpse_128636_register_event_post_type() {

    $labels = array(
        'name' => __( 'Eventos' ),
        'singular_name' => __( 'Evento' ),
        'add_new' => __( 'Añadir nuevo' ),
        'add_new_item' => __( 'Añadir nuevo' ),
        'edit_item' => __( 'Editar' ),
        'new_item' => __( 'Nuevo' ),
        'view_item' => __( 'Ver' ),
        'search_items' => __( 'Buscar' ),
        'not_found' => __( 'No encontrado' ),
        'not_found_in_trash' => __( 'No se encontraron Eventos en la papelera' ),
        'parent_item_colon' => __( 'Padre' ),
        'menu_name' => __( 'Eventos' ),

    );

    $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%' ); // Esta línea eliminará las reglas de reescritura para la vista individual
}

add_action( 'init', 'wpse_128636_register_event_post_type' );

Otro beneficio es que a partir de ahora puedes crear páginas simples de WordPress utilizando la estructura de enlaces permanentes del tipo de publicación 'event' (event/pagina-simple), lo que puede ser útil en sitios web complejos.

Recuerda limpiar las reglas de reescritura después de modificar el código.

25 sept 2019 12:50:03
Comentarios

Esta debería ser la respuesta aceptada, es corta, simple y no afecta las páginas de archivo.

artist learning to code artist learning to code
12 jun 2020 23:17:22

En mi caso, convierte las páginas individuales en páginas 404, pero YOAST SEO sigue incluyendo los enlaces en su mapa del sitio XML.

Jordan Carter Jordan Carter
23 abr 2021 20:13:26
0

En WordPress 5.9.0 se añadió un nuevo filtro que permite no solo deshabilitar el single sino también eliminar cualquier enlace hacia él en las pantallas de administración.

add_filter( 'is_post_type_viewable', function( $is_viewable, $post_type ) {
    if ( 'sample_post_type' === $post_type->name ) {
        return false;
    }
    return $is_viewable;
}, 10, 2 );

El single no cargará, pero si introduces la URL manualmente, se cargará la página de inicio en lugar de un 404. Para mostrar un 404 en vez de la página de inicio, puedes eliminar la regla de rewrite después de registrar el tipo de contenido.

remove_rewrite_tag( '%sample_post_type%' );

Después de realizar estos cambios, necesitarás limpiar las reglas de rewrite.

Usando estos 2 métodos lograrás el objetivo sin necesidad de plantillas adicionales, redirecciones o enlaces rotos en el admin.

21 mar 2022 16:43:57
0

Mi solución actual (principalmente "la solución de redirección") con una ligera diferencia en la implementación.

Esto mantendrá habilitadas las páginas de archivo (has_archive = TRUE)

Pero permitirá habilitar o deshabilitar las páginas individuales cuando uses register_post_type() con x_has_single = TRUE (el parámetro se pasa junto con las propiedades del objeto del tipo de contenido).

add_action( 'init', function() {
    $args = [
        ... // otras variables
        'public'             => FALSE,
        'publicly_queryable' => TRUE,
        'show_ui'            => TRUE,
        'has_archive'        => 'customers',
        'rewrite'            => [ 'slug' => 'customers', 'with_front' => FALSE ],
        'x_has_single'       => FALSE,
    ];
    register_post_type( 'customers', $args );
} );

add_action( 'template_redirect', function() {
    $post_type = get_post_type() ?: FALSE;
    $post_type_obj = get_post_type_object( $post_type );
    $has_single = $post_type_obj->x_has_single ?? TRUE;
    if ( FALSE === $has_single && $post_type && is_singular( $post_type ) ) {
        wp_redirect( get_post_type_archive_link( $post_type ) ?: '/', 301 );
        exit;
    }
} );
27 sept 2022 03:57:30