Come disabilitare la visualizzazione singola per un custom post type?

5 gen 2014, 16:05:33
Visualizzazioni: 126K
Voti: 75

Dato questo custom post type:

register_post_type(
    'sample_post_type',
    [
        'labels' => [
            'name' => _x('Post di Esempio', 'nome generale del tipo di post'),
            'singular_name' => _x('Post di Esempio', 'nome singolare del tipo di post'),
        ],
        'public' => true,
        'show_in_nav_menus' => false,
        'exclude_from_search' => true,
    ]
);

Come posso disabilitare la visualizzazione del post singolo per questo particolare tipo di post? Va bene mostrare una semplice pagina 404 o reindirizzare alla homepage. Dato che questo è un plugin, non posso creare un file single-sample_post_type.php per impostare una pagina vuota.

0
Tutte le risposte alla domanda 9
4
107

Basta impostare l'argomento

'publicly_queryable'  => false

quando chiami register_post_type()

27 dic 2014 23:38:13
Commenti

Sembra essere la soluzione per impedire al tuo CPT di creare pagine web effettive mantenendo comunque tutti i riferimenti al database.

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

Questo nasconde anche l'archivio

spaceman spaceman
11 ott 2016 19:12:19

Questa dovrebbe essere la risposta accettata.

SinisterBeard SinisterBeard
16 mar 2018 12:26:45

Per me questo causa un reindirizzamento alla homepage invece di un errore 404. Qualcuno ha idee sul perché? Sto registrando il post_type con Piklist, nel caso sia rilevante.

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

Per disabilitare la visualizzazione singola per un CPT puoi reindirizzare gli utenti a un URL specifico, oppure disabilitarla durante la registrazione del CPT stesso.

METODO 1:

Reindirizza la visualizzazione singola del CPT a un URL personalizzato, la pagina archivio rimane pubblicamente disponibile.

Puoi usare l'hook template_redirect per reindirizzare un utente, puoi usare qualsiasi URL al posto di home_url() e il codice di errore desiderato come secondo argomento.

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

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

METODO 2:

Disabilita completamente la pagina Singola e Archivio dal front-end; Funziona solo per Custom Post Types.

Un approccio alternativo è impostare publicly_queryable su false durante la registrazione del post personalizzato.

'publicly_queryable'  => false

Questo nasconde sia la visualizzazione singola che la pagina archivio per il CPT, può essere usato solo per post personalizzati.

Anche se l'archivio e la visualizzazione singola sono nascosti, puoi comunque aggiungere un template di pagina o un blocco personalizzato per elencare i post se necessario.

5 gen 2014 16:12:14
Commenti

Una buona soluzione. Ho trovato utile eseguire questo reindirizzamento solo per gli utenti non autenticati, verificando se get_current_user_id() restituisce 0.

RevNoah RevNoah
29 giu 2015 16:25:32

Per favore controlla la risposta di @Gustavo

Richard Richard
18 nov 2016 11:17:44

perché non usare solo is_singular('post-type-slug') nella condizione if() invece di 2 condizioni?

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

@AkashK. Sì, anche quello potrebbe funzionare, non conoscevo la funzione.

Kumar Kumar
23 ott 2018 09:26:50

il suggerimento remove_rewrite_tag( '%post-type-slug%' ); è una buona soluzione

Pbearne Pbearne
5 mag 2020 01:20:44

Manca la parentesi di chiusura nel codice - dovrebbe essere...

if ( is_singular( 'sample_post_type' ) )

neilgee neilgee
18 ago 2020 07:31:26
Mostra i restanti 1 commenti
6
17

Ho testato tutte le soluzioni menzionate sopra e la soluzione effettiva è più semplice di qualsiasi reindirizzamento suggerito.

Per avere l'archivio accessibile e che elenchi gli elementi, e il singolo post non accessibile con reindirizzamento automatico alla pagina 404, imposta

'query_var' => false

durante la registrazione del tuo CPT. Se imposti publicly_queryable su false, i tuoi archivi verranno reindirizzati alla home, qualsiasi altra combinazione non funzionerà. Imposta query_var su false e il gioco è fatto.

Ecco il CPT completo https://gist.github.com/danyj/bfd038d3c8d578548c4d700bd0a7942a

vedi riga 50 https://gist.github.com/danyj/bfd038d3c8d578548c4d700bd0a7942a#file-thz_cpt_items_single_view_redirect-php-L50

come indicato qui

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

Nota: Se query_var è vuoto, null, o un booleano FALSE, WordPress cercherà comunque di interpretarlo (4.2.2) e le anteprime/visualizzazioni del tuo custom post restituiranno errori 404.

17 nov 2018 00:22:57
Commenti

Sembra un po' un hack ma sembra funzionare. Vorrei che aggiungessero semplicemente una proprietà dedicata has_single insieme alla proprietà esistente has_archive.

powerbuoy powerbuoy
31 gen 2019 15:40:15

Ciao, ho provato a fare lo stesso ma non ha funzionato. Nonostante abbia impostato query_var su false, riesco ancora a visitare i link delle pagine singole. Puoi aiutarmi?

iSaumya iSaumya
13 ott 2020 15:08:30

@iSaumya prova a svuotare i tuoi permalink (vai nella pagina dei permalink e salva di nuovo) o usa il comando wp-cli wp rewrite flush && wp cache flush

thetwopct thetwopct
28 mag 2021 19:23:36

Non funziona più (agosto 2022). La nota che le visualizzazioni singole sono state rimosse non esiste più nemmeno nella documentazione.

Blorf Blorf
30 ago 2022 18:02:34

@blorf la nota è ancora nella documentazione - è elencata sotto publicly_queryable

rtpHarry rtpHarry
11 set 2022 15:54:33

Questo funziona per me, ho Elementor con JetEngine e sto configurando il tipo di post con public, publicly_queryable e has_archive impostati su true, con query_var impostato su false. I miei archivi funzionano e le pagine singole reindirizzano alla homepage con un 301.

rtpHarry rtpHarry
11 set 2022 15:59:56
Mostra i restanti 1 commenti
3
10

Un modo più semplice per farlo può essere passare i seguenti argomenti durante la registrazione del Custom Post Type

register_post_type('sample_post_type',array(
'labels' => array(
    'name' => _x('Post di Esempio', 'nome generale del post type'),
    'singular_name' => _x('Post di Esempio', 'nome singolare del post type')
),
'public' => true,
'exclude_from_search' => true,
'show_in_admin_bar'   => false,
'show_in_nav_menus'   => false,
'publicly_queryable'  => false,
'query_var'           => false
));
24 mag 2014 22:01:04
Commenti

In realtà avresti bisogno che publically_querable sia impostato su true affinché gli archivi dei Post Type funzionino.

Howdy_McGee Howdy_McGee
12 nov 2014 21:42:28

Questo non funziona per me. Quando provo ad accedere all'archivio, viene semplicemente reindirizzato alla homepage

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

Impostare query_var su false disabilita solo l'uso delle query vars nell'URL, cioè /?sample_post_type=sample_slug, ma non impedisce di accedervi tramite /sample_post_type/sample_slug/

Enchiridion Enchiridion
5 gen 2021 07:57:12
3

Uno. Dal tuo file functions.php.

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

Due. Dal tuo file single.cpt.php:

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

Mi piaceva la seconda opzione. Ma ho bisogno di sapere se ci sono svantaggi con questa seconda opzione.

user2584538 user2584538
10 ott 2017 09:27:08

@user2584538 Se non hai un file personalizzato single-cpt_name.php non potresti farlo. Se metti la funzione in un semplice file plugin, potresti attivarlo/disattivarlo senza modificare alcun file.

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

Lo svantaggio sarebbe probabilmente in termini di SEO. Per qualsiasi di queste risposte. Raccomanderei di aggiungere il seguente meta tag <meta name="robots" content="none, nosnippet, noarchive" /> su ogni pagina che decidi di reindirizzare.

amarinediary amarinediary
2 gen 2021 04:12:57
3

Basandomi sulla risposta davvero buona di Sven, ho riscritto la sua funzione per rendere più semplice aggiungere più tipi di post utilizzando in_array() nell'istruzione if e poi reindirizzando alla pagina archivio invece che alla home page.

(tra l'altro, penso che impostare query_var e/o publically_queryable su false disabiliti non solo le viste singole, ma anche la vista archivio nativa, sovrascrivendo 'has_archive' => true. In quel caso puoi comunque configurare una WP_query personalizzata e creare la tua pagina archivio, in un template, ma la query principale non lo farà più, giusto?)

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' );
9 lug 2016 19:27:21
Commenti

era una buona idea, ma non funziona se cambi il reindirizzamento per i CPT

rudtek rudtek
23 mar 2020 19:57:53

Ho modificato la tua riga wp_redirect in wp_redirect( get_post_type_archive_link( $queried_post_type ), 301 ); funziona perfettamente!

rudtek rudtek
23 mar 2020 20:06:25

Ottimo. Bel miglioramento.

slashbob slashbob
24 mar 2020 23:18:25
2

Se desideri disabilitare completamente la visualizzazione singola di un custom post type nel frontend ma mantenere la possibilità di visualizzare la pagina archivio, le cose si complicano leggermente.

Impostare publicly_queryable a false o rewrite a false impedirà la visualizzazione sia della vista singola che dell'archivio. Non esiste un flag negli argomenti della funzione register_post_type per prevenire la creazione delle regole di rewrite solo per la vista singola.

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

Tuttavia, puoi rimuovere il tag di rewrite dopo aver registrato il tuo post type e questo lascerà intatte le regole di rewrite per la vista archivio, rimuovendo solo quelle per la vista singola.

/**
 * Registra il post type per gli eventi
 */
function wpse_128636_register_event_post_type() {

    $labels = array(
        'name' => __( 'Eventi' ),
        'singular_name' => __( 'Evento' ),
        'add_new' => __( 'Aggiungi nuovo' ),
        'add_new_item' => __( 'Aggiungi nuovo' ),
        'edit_item' => __( 'Modifica' ),
        'new_item' => __( 'Nuovo' ),
        'view_item' => __( 'Visualizza' ),
        'search_items' => __( 'Cerca' ),
        'not_found' => __( 'Non trovato' ),
        'not_found_in_trash' => __( 'Nessun Evento trovato nel cestino' ),
        'parent_item_colon' => __( 'Genitore' ),
        'menu_name' => __( 'Eventi' ),

    );

    $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' => 'evento'),
        'capability_type' => 'post',
    );

    register_post_type( 'event', $args );
    remove_rewrite_tag( '%event%' ); // Questa riga rimuoverà le regole di rewrite per la vista singola degli eventi
}

add_action( 'init', 'wpse_128636_register_event_post_type' );

Un ulteriore vantaggio è che da ora in poi puoi creare semplici pagine WordPress utilizzando la struttura dei permalink del post type evento (evento/pagina-semplice), il che può essere utile in siti web complessi.

Ricorda di svuotare le regole di rewrite dopo aver modificato il codice.

25 set 2019 12:50:03
Commenti

Questa dovrebbe essere la risposta accettata, è breve, semplice e non interferisce con le pagine di archivio.

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

Nel mio caso, trasforma le pagine singole in pagine 404, ma YOAST SEO continua comunque a inserire i link nella sua mappa XML del sito.

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

In WordPress 5.9.0 è stato aggiunto un nuovo filtro che consente non solo di disabilitare il single post ma anche di rimuovere qualsiasi link ad esso dagli schermi di amministrazione.

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

Il single post non verrà caricato ma se si inserisce l'URL manualmente, verrà caricata la home page invece di un 404. Per mostrare un 404 invece della home page, è possibile rimuovere la regola di rewrite dopo la registrazione del post type.

remove_rewrite_tag( '%sample_post_type%' );

Dopo aver apportato queste modifiche sarà necessario ripulire le regole di rewrite.

Utilizzando questi 2 metodi si raggiungerà l'obiettivo senza template aggiuntivi, redirects e link rotti nell'admin.

21 mar 2022 16:43:57
0

La mia soluzione attuale (principalmente "la soluzione di reindirizzamento") con una leggera differenza nell'implementazione.

Questo manterrà abilitate le pagine di archivio (has_archive = TRUE)

Ma ti permetterà di abilitare o disabilitare le pagine singole quando usi register_post_type() con x_has_single = TRUE (il parametro viene passato insieme alle proprietà dell'oggetto post type).

add_action( 'init', function() {
    $args = [
        ... // altre variabili
        '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 set 2022 03:57:30