Rimuovere lo slug dagli URL dei post dei tipi di contenuto personalizzati

28 set 2015, 19:18:46
Visualizzazioni: 164K
Voti: 84

Sembra che tutte le risorse web basate sul tema della rimozione dello slug di un tipo di contenuto personalizzato, cioè

yourdomain.com/CPT-SLUG/post-name 

siano ormai soluzioni molto datate che spesso fanno riferimento a installazioni precedenti a WP versione 3.5. Una soluzione comune è:

'rewrite'   => array( 'slug' => false, 'with_front' => false ),  

all'interno della funzione register_post_type. Questo non funziona più ed è fuorviante. Quindi chiedo alla community nel Q4 2020...

Quali sono i modi moderni ed efficienti per rimuovere lo Slug del Tipo di Post dall'URL di un Post Type personalizzato dall'interno dell'argomento rewrite o da qualsiasi altra parte?

AGGIORNAMENTO: Sembrano esserci diversi modi per forzare questo funzionamento con le regex. In particolare la risposta di Jan Beck, nel caso in cui si sia costantemente disposti a monitorare la creazione dei contenuti per assicurarsi che non vengano creati nomi di pagine/post in conflitto.... Tuttavia sono convinto che questa sia una grande debolezza nel core di WP che dovrebbe essere gestita per noi. Sia come opzione/hook durante la creazione di un CPT sia come set avanzato di opzioni per i permalink. Si prega di supportare il ticket di track.

Nota a piè di pagina: Si prega di supportare questo ticket trac osservandolo/promuovendolo: https://core.trac.wordpress.org/ticket/34136#ticket

3
Commenti

Mi chiedo perché vorresti farlo? Sono confuso.

Michael Ecklund Michael Ecklund
29 mag 2017 18:22:54

@MichaelEcklund perché qualsiasi CPT utilizzato per creare pagine web pubbliche ha un nome di slug forzato nell'URL. In realtà ci sono molti sviluppatori WP che cercano di rimuovere lo slug in modo sicuro.

Ben Racicot Ben Racicot
18 lug 2017 03:11:36

Questa domanda (insieme ad altre cose su WP...) segna il momento in cui la mia carriera si allontana da WordPress.

Ben Racicot Ben Racicot
14 mar 2025 16:17:22
Tutte le risposte alla domanda 15
15
102

Il seguente codice funzionerà, ma devi tenere a mente che possono verificarsi facilmente conflitti se lo slug del tuo custom post type è uguale a quello di una pagina o articolo...

Per prima cosa, rimuoveremo lo slug dal permalink:

function na_remove_slug( $post_link, $post, $leavename ) {

    if ( 'events' != $post->post_type || 'publish' != $post->post_status ) {
        return $post_link;
    }

    $post_link = str_replace( '/' . $post->post_type . '/', '/', $post_link );

    return $post_link;
}
add_filter( 'post_type_link', 'na_remove_slug', 10, 3 );

Rimuovere solo lo slug non è sufficiente. Al momento otterrai una pagina 404 perché WordPress si aspetta che solo articoli e pagine si comportino in questo modo. Dovrai anche aggiungere quanto segue:

function na_parse_request( $query ) {

    if ( ! $query->is_main_query() || 2 != count( $query->query ) || ! isset( $query->query['page'] ) ) {
        return;
    }

    if ( ! empty( $query->query['name'] ) ) {
        $query->set( 'post_type', array( 'post', 'events', 'page' ) );
    }
}
add_action( 'pre_get_posts', 'na_parse_request' );

Basta cambiare "events" con il tuo custom post type e sei a posto. Potresti dover aggiornare i tuoi permalink.

30 set 2015 23:45:51
Commenti

grazie. Pensi che questo sia meglio rispetto a creare i rewrite manualmente? Ho visto quella soluzione e potrebbe tenere a bada i conflitti che menzioni?

Ben Racicot Ben Racicot
1 ott 2015 16:29:45

Penso che questa sia una buona soluzione automatizzata se sei sicuro di non creare conflitti. Non è una buona soluzione se la stai fornendo a... diciamo un cliente che non è esperto di tecnologia.

Nate Allen Nate Allen
1 ott 2015 16:53:24

puoi per favore aggiornare, come usare questo codice per più tipi di post

Abin Abin
25 gen 2016 13:29:09

Fallisce con nginx a causa della condizione 2 != count( $query->query ). Con nginx, puoi avere $query->query come array('page' => '', 'name' => '...', 'q' => '...'). Quindi @NateAllen, qual è il significato di quella condizione?

Fabio Montefuscolo Fabio Montefuscolo
8 nov 2016 14:25:05

Abbiamo bisogno di qualcosa di meglio di questo. Un supporto integrato per rimuovere lo slug in modo da non creare URL conflittuali in seguito. Il modo in cui i post regolari e le pagine creano i loro URL.

Ben Racicot Ben Racicot
18 lug 2017 03:13:34

Sono solo io o questo rompe alcuni tag condizionali di WordPress come is_single() e is_singular()?

rob-gordon rob-gordon
18 lug 2017 21:53:38

Questa soluzione purtroppo ha causato alcuni link interrotti e il mio blog ha smesso di mostrare i post, diventando semplicemente una pagina normale. Vedi una soluzione migliore qui sotto proposta da Matt Keys.

Radley Sustaire Radley Sustaire
8 ott 2018 03:10:20

Questo codice presuppone che il nome del post_type sia lo stesso dello slug del custom post type, cosa che non è necessariamente vera in tutti i casi. Per il resto, ottima soluzione anche se concordo che una soluzione nativa di WP sarebbe migliore.

Marco Miltenburg Marco Miltenburg
14 giu 2019 23:26:35

single-{cpt}.php smette di funzionare utilizzando questo approccio

Saleh Mahmood Saleh Mahmood
5 gen 2020 15:24:10

Per chi ha problemi con il codice sopra, funziona perfettamente se sostituisci la seconda funzione ( function na_parse_request() ) con quella trovata in questa risposta. Non dimenticare di modificare il codice con il nome del tuo Custom Post Type.

PhpDoe PhpDoe
3 apr 2020 19:28:16

Ho utilizzato questo bel codice fino all'arrivo di WP 5.2. Dopo l'aggiornamento, questo codice ha iniziato a non funzionare correttamente sul mio plugin di Custom Post Type e sul plugin Advanced Custom Fields, perché, credo, stanno usando la stessa funzione pre_get_posts, quindi invece dei gruppi di Advanced Custom Fields vedo i miei post personalizzati in questo plugin... Inoltre non funziona con il plugin CPT UI - non è più possibile creare nuovi post, non compaiono più nell'elenco dopo la creazione. Aiuto!!

Gediminas Gediminas
4 mag 2020 15:58:12

Funziona per un singolo post type. Come posso utilizzare il codice per più post type?

Swaranan Singha Barman Swaranan Singha Barman
2 lug 2020 11:07:43

Funziona per me.

user9437856 user9437856
10 dic 2020 08:38:08

Ahh, finalmente una soluzione - grazie! Mi chiedevo perché improvvisamente ricevessi errori 404 per un'ora prima di realizzare che era a causa di questa cosa 'rewrite' => array( 'slug' => false) :)

Philarmon Philarmon
20 ago 2021 04:48:04

Questo può funzionare ma è un approccio che modifica WordPress. La risposta corretta è il Passo 1 di Matt Keys: basta definire correttamente il post type durante la registrazione: register_post_type( 'custom_post_type', array( 'rewrite' => false ) );

gtamborero gtamborero
23 set 2022 12:22:01
Mostra i restanti 10 commenti
10
34

Esaminando le risposte qui presenti, credo ci sia spazio per una soluzione migliore che combina alcune cose che ho imparato sopra e aggiunge il rilevamento automatico e la prevenzione di slug di post duplicati.

NOTA: Assicurati di sostituire 'custom_post_type' con il nome del tuo CPT nell'esempio qui sotto. Ci sono molte occorrenze, e un 'trova/sostituisci' è un modo semplice per catturarle tutte. Tutto questo codice può essere inserito nel tuo functions.php o in un plugin.

Passo 1: Disabilita i rewrite sul tuo custom post type impostando rewrites a 'false' quando registri il post:

register_post_type( 'custom_post_type',
    array(
        'rewrite' => false
    )
);

Passo 2: Aggiungi manualmente i nostri rewrite personalizzati in fondo ai rewrite di WordPress per il nostro custom_post_type

function custom_post_type_rewrites() {
    add_rewrite_rule( '[^/]+/attachment/([^/]+)/?$', 'index.php?attachment=$matches[1]', 'bottom');
    add_rewrite_rule( '[^/]+/attachment/([^/]+)/trackback/?$', 'index.php?attachment=$matches[1]&tb=1', 'bottom');
    add_rewrite_rule( '[^/]+/attachment/([^/]+)/feed/(feed|rdf|rss|rss2|atom)/?$', 'index.php?attachment=$matches[1]&feed=$matches[2]', 'bottom');
    add_rewrite_rule( '[^/]+/attachment/([^/]+)/(feed|rdf|rss|rss2|atom)/?$', 'index.php?attachment=$matches[1]&feed=$matches[2]', 'bottom');
    add_rewrite_rule( '[^/]+/attachment/([^/]+)/comment-page-([0-9]{1,})/?$', 'index.php?attachment=$matches[1]&cpage=$matches[2]', 'bottom');
    add_rewrite_rule( '[^/]+/attachment/([^/]+)/embed/?$', 'index.php?attachment=$matches[1]&embed=true', 'bottom');
    add_rewrite_rule( '([^/]+)/embed/?$', 'index.php?custom_post_type=$matches[1]&embed=true', 'bottom');
    add_rewrite_rule( '([^/]+)/trackback/?$', 'index.php?custom_post_type=$matches[1]&tb=1', 'bottom');
    add_rewrite_rule( '([^/]+)/page/?([0-9]{1,})/?$', 'index.php?custom_post_type=$matches[1]&paged=$matches[2]', 'bottom');
    add_rewrite_rule( '([^/]+)/comment-page-([0-9]{1,})/?$', 'index.php?custom_post_type=$matches[1]&cpage=$matches[2]', 'bottom');
    add_rewrite_rule( '([^/]+)(?:/([0-9]+))?/?$', 'index.php?custom_post_type=$matches[1]', 'bottom');
    add_rewrite_rule( '[^/]+/([^/]+)/?$', 'index.php?attachment=$matches[1]', 'bottom');
    add_rewrite_rule( '[^/]+/([^/]+)/trackback/?$', 'index.php?attachment=$matches[1]&tb=1', 'bottom');
    add_rewrite_rule( '[^/]+/([^/]+)/feed/(feed|rdf|rss|rss2|atom)/?$', 'index.php?attachment=$matches[1]&feed=$matches[2]', 'bottom');
    add_rewrite_rule( '[^/]+/([^/]+)/(feed|rdf|rss|rss2|atom)/?$', 'index.php?attachment=$matches[1]&feed=$matches[2]', 'bottom');
    add_rewrite_rule( '[^/]+/([^/]+)/comment-page-([0-9]{1,})/?$', 'index.php?attachment=$matches[1]&cpage=$matches[2]', 'bottom');
    add_rewrite_rule( '[^/]+/([^/]+)/embed/?$', 'index.php?attachment=$matches[1]&embed=true', 'bottom');
}
add_action( 'init', 'custom_post_type_rewrites' );

NOTA: A seconda delle tue esigenze, potresti voler modificare i rewrite sopra indicati (disabilitare i trackback? i feed?, ecc.). Questi rappresentano i rewrite 'predefiniti' che sarebbero stati generati se non avessi disabilitato i rewrite nel passo 1

Passo 3: Rendi nuovamente 'belli' i permalink per il tuo custom post type

function custom_post_type_permalinks( $post_link, $post, $leavename ) {
    if ( isset( $post->post_type ) && 'custom_post_type' == $post->post_type ) {
        $post_link = home_url( $post->post_name );
    }

    return $post_link;
}
add_filter( 'post_type_link', 'custom_post_type_permalinks', 10, 3 );

NOTA: Puoi fermarti qui se non sei preoccupato che i tuoi utenti creino un post conflittuale (duplicato) in un altro tipo di post che creerà una situazione in cui solo uno di essi potrà essere caricato quando la pagina viene richiesta.

Passo 4: Previeni slug di post duplicati

function prevent_slug_duplicates( $slug, $post_ID, $post_status, $post_type, $post_parent, $original_slug ) {
    $check_post_types = array(
        'post',
        'page',
        'custom_post_type'
    );
    
    if ( ! in_array( $post_type, $check_post_types ) ) {
        return $slug;
    }

    if ( 'custom_post_type' == $post_type ) {
        // Salvataggio di un post di tipo custom_post_type, controlla duplicati nei tipi di post POST o PAGE
        $post_match = get_page_by_path( $slug, 'OBJECT', 'post' );
        $page_match = get_page_by_path( $slug, 'OBJECT', 'page' );

        if ( $post_match || $page_match ) {
            $slug .= '-duplicate';
        }
    } else {
        // Salvataggio di un POST o PAGE, controlla duplicati nel tipo di post custom_post_type
        $custom_post_type_match = get_page_by_path( $slug, 'OBJECT', 'custom_post_type' );

        if ( $custom_post_type_match ) {
            $slug .= '-duplicate';
        }
    }

    return $slug;
}
add_filter( 'wp_unique_post_slug', 'prevent_slug_duplicates', 10, 6 );

NOTA: Questo aggiungerà la stringa '-duplicate' alla fine di qualsiasi slug duplicato. Questo codice non può prevenire slug duplicati se già esistono prima di implementare questa soluzione. Assicurati di controllare prima i duplicati.

Mi piacerebbe avere feedback da chiunque provi questa soluzione per vedere se ha funzionato bene anche per loro.

6 ott 2017 01:51:15
Commenti

L'ho appena testato e sembra funzionare finora.

Christine Cooper Christine Cooper
12 nov 2017 20:02:48

Speravo in questo approccio, ma mi restituisce un errore 404 sui miei post CPT, anche dopo aver ri-salvato i Permalink.

Garconis Garconis
7 ago 2018 21:32:09

Mi dispiace che non abbia funzionato per te Garconis. Ne avevo parlato con qualcun altro tempo fa e anche loro avevano problemi sul loro sito. Mi sembra di ricordare che dipendesse dal fatto che i permalink dei post del blog avessero o meno un prefisso. Sul sito per cui ho sviluppato questa soluzione, i post del blog utilizzano la struttura dei permalink: /blog/%postname%/. Se i tuoi post del blog non hanno un prefisso, e se per te va bene aggiungerlo, provalo e fammi sapere come va!

Matt Keys Matt Keys
7 ago 2018 23:54:20

Questa soluzione ha funzionato per me. A differenza di altre soluzioni sulla pagina, non ha rotto le pagine normali o il layout del blog, e non ha causato redirect infiniti. Mostra anche l'URL corretto nell'area "Permalink" quando si modificano quelle pagine CPT. Soluzione abbastanza buona qui, l'unica avvertenza è che la pagina archivio non funziona. RICORDA di sostituire "custom_post_type" e aggiornare i permalink successivamente.

Radley Sustaire Radley Sustaire
8 ott 2018 03:08:13

@MattKeys, le impostazioni predefinite dei Permalink hanno una Struttura Personalizzata di /%category%/%postname%/. Quando aggiungi il tuo codice, gli slug CPT appaiono OK (anche se mancano della barra finale) ... e anche il controllo dei conflitti funziona. Ma i risultati effettivi dei post mostrano un 404.

Garconis Garconis
3 lug 2019 17:39:38

Funziona benissimo! Tuttavia, ho dovuto aggiungere una variabile di query nel passo 2 add_rewrite_tag( "%custom_post_type%", '([^/]+)', "post_type=custom_post_type&name=" ); per vedere le pagine CPT invece di un messaggio 404

Philipp Philipp
8 mag 2021 19:16:55

Questa è l'unica soluzione che ha funzionato per me. Ho solo dovuto aggiungere una barra alla fine di return $post_link nel passo 3.

EmilyH EmilyH
26 ago 2021 22:44:03

Ha funzionato, ma manca la barra finale. Per favore aggiorna la risposta per includerla! Un potenziale svantaggio: non potrai più personalizzare il permalink dal front-end (ad esempio quando vuoi accorciarlo rispetto al titolo).

Alex Alex
18 ott 2021 17:01:31

Funziona bene per il CPT, ma fa andare in 404 tutti gli articoli del mio sito. Sto usando questo codice in un plugin, quindi deve funzionare con ogni possibile struttura di permalink, e non sono sicuro che sia possibile.

Morgan Kay Morgan Kay
15 feb 2024 22:32:55

@MorganKay sì, hai ragione, questo non può funzionare con tutte le possibili strutture di permalink. Quindi non sarà adatto per l'integrazione in qualcosa come un plugin che vuoi distribuire.

Matt Keys Matt Keys
23 feb 2024 00:33:21
Mostra i restanti 5 commenti
11
32

Scrivi il seguente codice nella registrazione della tassonomia.

'rewrite' => [
  'slug' => '/',
  'with_front' => false
]

La cosa più importante che devi fare dopo aver modificato il codice

Dopo aver modificato il documento della tassonomia del tuo custom post type, prova ad andare in Impostazioni > Permalink e risalva le impostazioni, altrimenti otterrai un errore 404 pagina non trovata.

12 apr 2017 21:16:53
Commenti

Funziona davvero, non so come nessuno l'abbia notato prima. Ovviamente questo può interferire con altre pagine se hanno lo stesso permalink, ma se non è così è un'ottima soluzione.

lonerunner lonerunner
31 lug 2017 20:33:02

L'ho provato. Fornisce il risultato desiderato per i link del mio custom post type. Tuttavia "cattura" tutti gli slug POST o PAGE e cerca di risolverli come URL per il mio custom post type, generando poi errori 404. (sì, ho salvato i permalink).

Matt Keys Matt Keys
5 ott 2017 23:49:14

Potrebbe esserci lo stesso slug per una pagina e un custom post type, cambia lo slug della tua pagina e poi verifica...

Mayank Dudakiya Mayank Dudakiya
11 ott 2017 19:51:23

Non funziona. Restituisce errore 404 anche dopo aver aggiornato i permalink.

Christine Cooper Christine Cooper
12 nov 2017 20:02:15

@ChristineCooper Devi seguire questo passaggio

Dopo aver modificato il documento della tassonomia del tuo custom post type, prova ad andare in Impostazioni > Permalink e ri-salva le impostazioni, altrimenti otterrai una pagina 404 non trovata.

Mayank Dudakiya Mayank Dudakiya
15 nov 2017 18:56:26

Come evidenziato nel mio ultimo commento, otterrai un errore 404 anche dopo aver aggiornato i permalink. Per favore provalo tu stesso.

Christine Cooper Christine Cooper
15 nov 2017 22:11:20

Funziona perfettamente, soprattutto quando si legge l'intero messaggio, inclusa la parte "salva nuovamente le tue impostazioni". +1

Dadou Dadou
25 gen 2018 16:12:26

Anche dopo aver salvato nuovamente le impostazioni dei permalink, i post e le pagine non funzionano più (errore 404)

amklose amklose
13 feb 2018 21:18:58

Questa soluzione funziona per rimuovere lo slug dall'URL. Ma le pagine archivio non funzionano più.

Annapurna Annapurna
25 set 2018 07:42:57

Come altri hanno affermato, questo funziona per i post CPT stessi. Ma ora sta causando un errore 404 per le Pagine regolari.

Garconis Garconis
3 lug 2019 19:52:06

Forse questo funziona per alcuni ma non per altri a causa di altri plugin che interferiscono? Ad esempio, non funziona neanche per me in un ambiente dove WPML con sottodirectory è configurato: www.mysite.com/en/CPT-item/ dà errore 404.

WoodrowShigeru WoodrowShigeru
21 mag 2021 19:22:31
Mostra i restanti 6 commenti
3
16

Ho cercato di capirlo non molto tempo fa e la risposta breve, per quanto ne so, è no. Almeno non dall'interno dell'argomento rewrite.

La spiegazione lunga diventa evidente se guardi il codice effettivo di register_post_type in wp-includes/post.php riga 1454:

add_permastruct( $post_type, "{$args->rewrite['slug']}/%$post_type%", $permastruct_args );

Puoi vedere che antepone $args->rewrite['slug'] al tag di rewrite %$post_type%. Si potrebbe pensare "allora impostiamo semplicemente lo slug a null" fino a quando non si guarda qualche riga più sopra:

if ( empty( $args->rewrite['slug'] ) )
    $args->rewrite['slug'] = $post_type;

Puoi vedere che la funzione si aspetta sempre un valore di slug che non sia vuoto e altrimenti utilizza il post type.

30 set 2015 17:01:33
Commenti

Grazie @JanBeck. C'è una ragione importante per cui questa cosa esiste? Perché non modificare questo file core con un condizionale per escludere certi tipi di post da questa regola?

Ben Racicot Ben Racicot
30 set 2015 21:02:57

Dovresti assegnare la risposta a Jan Beck. WordPress ha bisogno dello slug del post_type per instradare correttamente le richieste. Questa regola previene conflitti di nomi tra le pagine native di WP (che vengono visualizzate senza lo slug) e qualsiasi tipo di post personalizzato definito. Se rimuovi lo slug, WordPress non saprà la differenza tra una pagina chiamata "picnic" e un evento (custom post type) chiamato "picnic".

dswebsme dswebsme
30 set 2015 22:34:09

@dswebsme Concordo, ma ci sono situazioni in cui devi assolutamente cambiare l'URL. Quindi, a parte il motivo per cui non puoi farlo nativamente e non dovresti, come lo fai in modo efficiente?

Ben Racicot Ben Racicot
1 ott 2015 16:27:31
3
16

Rassegna Plugin

Siamo quasi nel 2020 e molte di queste risposte non funzionano più. Ecco la mia panoramica sulle opzioni attuali:

  • La risposta di Matt Keys sembra essere l'unica sulla strada giusta se cerchi una soluzione personalizzata. Nessuno dei plugin che ho trovato fa tutto ciò che è elencato qui, soprattutto il controllo dei duplicati. Questo approccio sembra un'ottima opportunità per un plugin se qualcuno volesse cimentarsi.
  • Permalink Manager Lite
    • Il migliore tra i plugin gratuiti che ho provato.
    • Offre il controllo completo sulla struttura dei permalink di Pagine/Articoli/CPT e permette che siano uguali. L'interfaccia grafica è di gran lunga la più ricca di funzionalità.
    • Permette di sovrascrivere completamente ogni singolo articolo e mostra qual era il permalink originale/predefinito, con la possibilità di resettarlo se necessario.
    • Supporta il multi-sito.
    • Non controlla i duplicati tra tipi di contenuto, il che è un peccato. Se una pagina e un CPT hanno lo stesso URL, viene caricata la pagina e il CPT risulta inaccessibile. Nessun avviso o errore, devi controllare manualmente i duplicati.
    • Tutte le funzionalità relative alle tassonomie sono nella versione PRO. I reminder per l'aggiornamento sono piuttosto invadenti.
  • Custom Permalinks
    • La versione gratuita offre molte funzionalità. I permalink per le tassonomie e il supporto premium sembrano essere le uniche cose riservate alla versione pro.
    • Permette di modificare il permalink completo per ogni singola pagina/articolo/CPT.
    • Supporta il multi-sito.
    • Non permette di modificare la struttura predefinita, quindi i tuoi Custom Post Type avranno ancora la forma esempio.com/slug-cpt/titolo-articolo ma puoi modificarli individualmente.
    • Non controlla i duplicati tra tipi di contenuto, il che è un peccato.
  • Custom Post Type Permalinks
    • Permette agli utenti non sviluppatori di modificare le cose che sono già facili da cambiare con register_post_type
    • Non permette di modificare lo slug base del CPT - solo la parte che viene dopo - quindi praticamente inutile per gli sviluppatori e per il problema sollevato in questa domanda.
  • remove base slug... - abbandonato da diversi anni... da non usare.
17 dic 2019 02:09:40
Commenti

Il plugin Permalink Manager Lite è senza dubbio la soluzione migliore: stabile, robusta, pulita e la versione gratuita ti consente di rimuovere la base dello slug. Funziona anche con Polylang! Testato su WordPress 5.4, con il tema TwentyTwenty, senza altri plugin attivati. Funziona perfettamente con i Custom Post Type, indipendentemente dal fatto che tu abbia creato un tipo gerarchico (con post figlio e nipote). Per chiunque cerchi una soluzione pulita.

PhpDoe PhpDoe
4 apr 2020 14:57:17

Bella panoramica. Il codice della mia risposta è stato eseguito su un sito client per anni senza alcun problema. L'unico svantaggio che alcuni hanno sottolineato nella mia soluzione è che non funziona sui permalink 'predefiniti' per il tipo di post 'blog' incorporato (post). Invece deve esserci un prefisso come: /blog/%postname%/. Per chi usa WordPress come CMS, potrebbero già farlo, ma per altri potrebbe essere un blocco purtroppo.

Matt Keys Matt Keys
1 feb 2021 22:23:09

Ho usato Permalink Manager Lite e funzionerà per la mia situazione

Tahir Shahzad Tahir Shahzad
28 gen 2022 19:51:07
3

In risposta alla mia precedente risposta: potresti ovviamente impostare il parametro rewrite su false quando registri un nuovo post type e gestire manualmente le regole di riscrittura in questo modo

<?php
function wpsx203951_custom_init() {

    $post_type = 'event';
    $args = (object) array(
        'public'      => true,
        'label'       => 'Eventi',
        'rewrite'     => false, // impostare sempre su false
        'has_archive' => true
    );
    register_post_type( $post_type, $args );

    // questi sono i tuoi argomenti effettivi per la riscrittura
    $args->rewrite = array(
        'slug' => 'calendario'
    );

    // tutto ciò che segue è preso dalla funzione register_post_type
    if ( is_admin() || '' != get_option( 'permalink_structure' ) ) {

        if ( ! is_array( $args->rewrite ) )
            $args->rewrite = array();
        if ( empty( $args->rewrite['slug'] ) )
            $args->rewrite['slug'] = $post_type;
        if ( ! isset( $args->rewrite['with_front'] ) )
            $args->rewrite['with_front'] = true;
        if ( ! isset( $args->rewrite['pages'] ) )
            $args->rewrite['pages'] = true;
        if ( ! isset( $args->rewrite['feeds'] ) || ! $args->has_archive )
            $args->rewrite['feeds'] = (bool) $args->has_archive;
        if ( ! isset( $args->rewrite['ep_mask'] ) ) {
            if ( isset( $args->permalink_epmask ) )
                $args->rewrite['ep_mask'] = $args->permalink_epmask;
            else
                $args->rewrite['ep_mask'] = EP_PERMALINK;
        }

        if ( $args->hierarchical )
            add_rewrite_tag( "%$post_type%", '(.+?)', $args->query_var ? "{$args->query_var}=" : "post_type=$post_type&pagename=" );
        else
            add_rewrite_tag( "%$post_type%", '([^/]+)', $args->query_var ? "{$args->query_var}=" : "post_type=$post_type&name=" );

        if ( $args->has_archive ) {
            $archive_slug = $args->has_archive === true ? $args->rewrite['slug'] : $args->has_archive;
            if ( $args->rewrite['with_front'] )
                $archive_slug = substr( $wp_rewrite->front, 1 ) . $archive_slug;
            else
                $archive_slug = $wp_rewrite->root . $archive_slug;

            add_rewrite_rule( "{$archive_slug}/?$", "index.php?post_type=$post_type", 'top' );
            if ( $args->rewrite['feeds'] && $wp_rewrite->feeds ) {
                $feeds = '(' . trim( implode( '|', $wp_rewrite->feeds ) ) . ')';
                add_rewrite_rule( "{$archive_slug}/feed/$feeds/?$", "index.php?post_type=$post_type" . '&feed=$matches[1]', 'top' );
                add_rewrite_rule( "{$archive_slug}/$feeds/?$", "index.php?post_type=$post_type" . '&feed=$matches[1]', 'top' );
            }
            if ( $args->rewrite['pages'] )
                add_rewrite_rule( "{$archive_slug}/{$wp_rewrite->pagination_base}/([0-9]{1,})/?$", "index.php?post_type=$post_type" . '&paged=$matches[1]', 'top' );
        }

        $permastruct_args = $args->rewrite;
        $permastruct_args['feed'] = $permastruct_args['feeds'];
        add_permastruct( $post_type, "%$post_type%", $permastruct_args );
    }
}
add_action( 'init', 'wpsx203951_custom_init' );

Puoi vedere che la chiamata add_permastruct ora non include più lo slug. Ho testato due scenari:

  1. Quando ho creato una pagina con lo slug "calendario", quella pagina viene sovrascritta dall'archivio del post type che utilizza anch'esso lo slug "calendario".

Schermata che mostra la sovrascrittura dello slug

  1. Quando ho creato una pagina con lo slug "mio-evento" e un evento (CPT) con lo slug "mio-evento", viene visualizzato il custom post type.

Schermata che mostra il custom post type

  1. Qualsiasi altra pagina non funziona. Se guardi l'immagine sopra diventa chiaro il perché: la regola del custom post type corrisponderà sempre a uno slug di pagina. Poiché WordPress non ha modo di identificare se si tratta di una pagina o di un custom post type che non esiste, restituirà un errore 404. Ecco perché hai bisogno di uno slug per identificare se si tratta di una pagina o di un CPT. Una possibile soluzione sarebbe intercettare l'errore e cercare una pagina che potrebbe esistere similmente a questa risposta.
2 ott 2015 15:13:12
Commenti

Quindi se l'obiettivo è rimuovere lo slug per i CPT, non potremmo semplicemente dare ai CPT un nome univoco che non entri in conflitto, visto che comunque non apparirà nell'URL? O è il nome del post che potrebbe creare conflitti se uguale a una pagina?

Ben Racicot Ben Racicot
2 ott 2015 17:35:15

Ho aggiornato la mia risposta per mostrare che questo in realtà rompe tutte le pagine. Senza uno slug, WP cercherà un CPT invece di una pagina e, se non lo trova, restituirà un errore. Quindi in realtà non è legato al nome del post.

Jan Beck Jan Beck
2 ott 2015 18:49:31

Capisco. Dovrebbero esserci regole di riscrittura che aggiungono '-1' agli URL in conflitto futuri, come avviene nativamente tra i post e le pagine di WP. Ho creato un ticket trac https://core.trac.wordpress.org/ticket/34136#ticket e mi piacerebbe conoscere il tuo parere.

Ben Racicot Ben Racicot
3 ott 2015 02:22:54
3

Contesto

Anche dopo aver cercato ovunque, non sono riuscito a trovare una soluzione adeguata per rimuovere lo slug CPT dai permalink che funzioni davvero e sia coerente con il modo in cui WordPress analizza effettivamente le richieste. Sembra che tutti gli altri alla ricerca della stessa soluzione siano nella mia stessa situazione.

Si scopre che si tratta in realtà di una soluzione in due parti.

  1. Rimuovere lo slug CPT dai permalink
  2. Indicare a WordPress come trovare i post dai nuovi permalink

La prima parte è abbastanza semplice e molte risposte esistenti l'hanno già corretta. Ecco come si presenta:

// rimuovi lo slug CPT dai permalink
function remove_cpt_slug( $post_link, $post, $leavename ) {

    if ( $post->post_type != 'custom_post_type' ) {
        return $post_link;
    } else {
        $post_link = str_replace( '/' . $post->post_type . '/', '/', $post_link );
        return $post_link;
    }
}
add_filter( 'post_type_link', 'remove_cpt_slug', 10, 3 );

Ora, la seconda parte è dove le cose si complicano. Dopo aver risolto la prima parte, i tuoi permalink CPT non hanno più gli slug CPT. Ma ora il problema è che WordPress non sa come trovare i tuoi post da quei nuovi permalink perché tutto ciò che sa è che i permalink CPT hanno gli slug CPT. Quindi, senza uno slug CPT nel permalink, non riesce a trovare il tuo post. Ecco perché quando fai una richiesta per i tuoi post a questo punto, restituisce un errore 404 non trovato.

Quindi, tutto ciò che devi fare ora è indicare a WordPress come trovare i tuoi post utilizzando i nuovi permalink. Ma questa è la parte in cui le risposte esistenti non funzionano molto bene. Diamo un'occhiata ad alcune di queste risposte per esempio:

La funzione qui sotto funziona abbastanza bene ma funzionerà solo se la struttura dei permalink è impostata su Nome articolo.

function parse_request_remove_cpt_slug( $query ) {

    if ( ! $query->is_main_query() || 2 != count( $query->query ) || ! isset( $query->query['page'] ) ) {
        return;
    }

    if ( ! empty( $query->query['name'] ) ) {
        global $wpdb;
        $cpt = $wpdb->get_var("SELECT post_type FROM $wpdb->posts WHERE post_name = '{$query->query['name']}'");

        // Aggiungi CPT alla lista dei tipi di post che WP includerà quando esegue una query basata sul nome del post.
        $query->set( 'post_type', $cpt );
    }
}
add_action( 'pre_get_posts', 'parse_request_remove_cpt_slug' );

La funzione qui sotto funziona bene per il tuo tipo di post personalizzato indipendentemente dalla struttura del permalink, tuttavia genererà un errore su tutti gli altri tipi di post.

function rewrite_rule_remove_cpt_slug() {

    add_rewrite_rule(
        '(.?.+?)(?:/([0-9]+))?/?$',
        'index.php?custom_post_type=$matches[1]/$matches[2]&post_type=custom_post_type',
        'bottom'
    );
}
add_action( 'init', 'rewrite_rule_remove_cpt_slug', 1, 1 );

C'è un'altra risposta che dovrebbe funzionare come soluzione autonoma ma finisce per causare più problemi che soluzioni, come generare errori nei tuoi post CPT così come in altri. Questa richiede la modifica dell'argomento rewrite nella registrazione del tuo CPT come segue:

'rewrite' => array( 'slug' => '/', 'with_front' => false )

Finora, tutte le risposte esistenti che ho trovato sono come quelle sopra. O funzionano parzialmente o non funzionano più. Questo probabilmente perché WordPress non fornisce un modo semplificato per rimuovere lo slug CPT dai permalink dei tipi di post personalizzati e quindi queste risposte sono basate su scenari particolari o su un modo approssimativo.

Risposta

Ecco cosa ho ideato cercando di creare una soluzione che funziona nella maggior parte se non in tutti gli scenari. Questo rimuoverà correttamente lo slug CPT dai permalink CPT e indicherà a WordPress come trovare i post CPT da quei nuovi permalink. Non riscrive le regole nel database quindi non sarà necessario salvare nuovamente la struttura dei permalink. Inoltre, questa soluzione è coerente con il modo in cui WordPress analizza effettivamente le richieste per trovare i post dai permalink, il che aiuta a renderla una soluzione più accettabile.

Assicurati di sostituire custom_post_type con il nome del tuo tipo di post personalizzato. Appare una volta in ogni funzione quindi due occorrenze in totale.

// rimuovi lo slug CPT dai permalink
function remove_cpt_slug( $post_link, $post, $leavename ) {

    if ( $post->post_type != 'custom_post_type' ) {
        return $post_link;
    } else {
        $post_link = str_replace( '/' . $post->post_type . '/', '/', $post_link );
        return $post_link;
    }
}
add_filter( 'post_type_link', 'remove_cpt_slug', 10, 3 );


// indica a wordpress come trovare i post dai nuovi permalink
function parse_request_remove_cpt_slug( $query_vars ) {

    // esci se siamo nel pannello di amministrazione 
    if ( is_admin() ) {
        return $query_vars;
    }

    // esci se i permalink personalizzati non sono abilitati
    if ( ! get_option( 'permalink_structure' ) ) {
        return $query_vars;
    }

    $cpt = 'custom_post_type';

    // memorizza il valore dello slug del post in una variabile
    if ( isset( $query_vars['pagename'] ) ) {
        $slug = $query_vars['pagename'];
    } elseif ( isset( $query_vars['name'] ) ) {
        $slug = $query_vars['name'];
    } else {
        global $wp;
        
        $path = $wp->request;

        // usa il percorso dell'url come slug
        if ( $path && strpos( $path, '/' ) === false ) {
            $slug = $path;
        } else {
            $slug = false;
        }
    }

    if ( $slug ) {
        $post_match = get_page_by_path( $slug, 'OBJECT', $cpt );

        if ( ! is_admin() && $post_match ) {

            // rimuovi qualsiasi elemento di errore 404 non trovato dall'array query_vars perché esiste già una corrispondenza nel cpt
            if ( isset( $query_vars['error'] ) && $query_vars['error'] == 404 ) {
                unset( $query_vars['error'] );
            }

            // rimuovi elementi non necessari dall'array query_vars originale
            unset( $query_vars['pagename'] );
    
            // aggiungi elementi necessari nell'array query_vars
            $query_vars['post_type'] = $cpt;
            $query_vars['name'] = $slug;
            $query_vars[$cpt] = $slug; // questo costruisce l'elemento "cpt=>post_slug"
        }
    }

    return $query_vars;
}
add_filter( 'request', "parse_request_remove_cpt_slug" , 1, 1 );

Considerazioni:

  1. Questa soluzione lascia intenzionalmente fuori dal suo ambito la struttura di permalink Semplice poiché non è una delle strutture di permalink personalizzati. Quindi, funzionerà con tutte le strutture di permalink tranne quella Semplice.

  2. Poiché WordPress non previene automaticamente la creazione di slug duplicati tra diversi tipi di post, potresti riscontrare problemi nell'accesso ai post che hanno lo stesso slug a causa della perdita di unicità nei permalink CPT dopo la rimozione degli slug CPT. Questo codice non include alcuna funzionalità per prevenire tale comportamento, quindi potresti voler trovare una soluzione separata per affrontare questo problema.

  3. In caso di un permalink duplicato, questo codice darà priorità al tuo CPT rispetto agli altri e quindi visualizzerà il post nel tuo CPT quando richiesto.

26 mag 2021 21:16:58
Commenti

Al momento della scrittura, questa soluzione è la migliore. È semplice e corretta. La sua logica è facile da comprendere e personalizzare. Infatti, ho personalizzato questa soluzione per rimuovere anche gli slug delle tassonomie.

Tom Nguyen Tom Nguyen
23 gen 2024 09:27:40

Per evitare la creazione di slug duplicati, puoi leggere e personalizzare il codice nel "Passo 4" della risposta di Matt Keys.

Tom Nguyen Tom Nguyen
30 gen 2024 17:07:22

Ho consolidato questo codice e quello di Matt Keys in questo gist, necessita ulteriori test ma sembra funzionare bene. Fondamentalmente ho solo modificato il -duplicato per lo slug in qualcosa come -1,-2 ecc. Sicuramente c'è un modo migliore per farlo. Potrebbe anche essere carino costruire una piccola interfaccia attorno per impostare 'location' allo slug CPT desiderato. https://gist.github.com/cdsaenz/291d9599e1f20313c3a87edf48233176

cdsaenz cdsaenz
31 gen 2025 19:35:01
0

e possiamo apportare alcune modifiche alla funzione menzionata sopra:

function na_parse_request( $query ) {

if ( ! $query->is_main_query() || 2 != count( $query->query ) || ! isset( $query->query['page'] ) ) {
    return;
}

if ( ! empty( $query->query['name'] ) ) {
    $query->set( 'post_type', array( 'post', 'events', 'page' ) );
}
}

in:

function na_parse_request( $query ) {

if ( ! $query->is_main_query() || 2 != count( $query->query ) || ! isset( $query->query['page'] ) ) {
    return;
}

if ( ! empty( $query->query['name'] ) ) {

    global $wpdb;
    $pt = $wpdb->get_var(
        "SELECT post_type FROM `{$wpdb->posts}` " .
        "WHERE post_name = '{$query->query['name']}'"
    );
    $query->set( 'post_type', $pt );
}
}

per impostare il valore corretto di post_type.

1 mar 2017 13:50:14
1

Questo ha funzionato per me: 'rewrite' => array('slug' => '/')

3 mag 2017 19:39:48
Commenti

Non funziona. Restituisce un errore 404 anche dopo aver aggiornato i permalink.

Christine Cooper Christine Cooper
12 nov 2017 20:02:23
1

Per chiunque stia leggendo questo post e abbia avuto problemi con i post figli come ho avuto io, ho scoperto che il modo migliore è aggiungere le proprie regole di rewrite.

Il problema principale che ho riscontrato è che WordPress gestisce il reindirizzamento da pagine che sono a 2 livelli di profondità (post figli) in modo leggermente diverso rispetto a pagine a 3 livelli di profondità (figli di post figli).

Ciò significa che quando ho /tipo-di-post/nome-post/figlio-post/ posso usare /nome-post/figlio-post e verrò reindirizzato alla versione con tipo-di-post all'inizio, ma se ho tipo-di-post/nome-post/figlio-post/nipote-post allora non posso usare nome-post/figlio-post/nipote-post.

Analizzando le regole di rewrite, sembra che corrisponda a elementi diversi da pagename al primo e secondo livello (penso che il secondo livello corrisponda agli allegati) e poi esegue qualcosa per reindirizzarti al post corretto. A tre livelli di profondità non funziona.

La prima cosa da fare è rimuovere il link del post type anche dai figli. Questa logica dovrebbe avvenire qui se guardi la risposta di Nate Allen sopra:

$post_link = str_replace( '/' . $post->post_type . '/', '/', $post_link );

Personalmente ho usato un mix di diversi condizionali per verificare se il post aveva figli e simili per ottenere il permalink corretto. Questa parte non è troppo complicata e troverai esempi di persone che lo fanno altrove.

Il passo successivo però è dove le cose cambiano rispetto alla risposta data. Invece di aggiungere elementi alla query principale (che funzionava per i post personalizzati e i loro figli ma non per i figli successivi) ho aggiunto una regola di rewrite che andava in fondo alle regole di WordPress in modo che se pagename non fosse verificato e fosse sul punto di restituire un 404, avrebbe effettuato un ultimo controllo per vedere se una pagina all'interno del custom post type aveva lo stesso nome, altrimenti avrebbe restituito il 404.

Ecco la regola di rewrite che ho usato assumendo che 'event' sia il nome del tuo CPT

function rewrite_rules_for_removing_post_type_slug()
{
    add_rewrite_rule(
        '(.?.+?)(?:/([0-9]+))?/?$',
        'index.php?event=$matches[1]/$matches[2]&post_type=event',
        'bottom'
    );
}

add_action('init', 'rewrite_rules_for_removing_post_type_slug', 1, 1);

Spero che questo aiuti qualcun altro, non ho trovato nient'altro che riguardasse i figli dei post figli e la rimozione dello slug da quelli.

29 mag 2017 06:34:40
Commenti

Sembra esserci un errore di battitura nella regex. Tra '(:' è necessario un '?' per usarlo come sotto-pattern non catturante => '(?:'. Il terzo ? sembra posizionato male in quanto permette un primo sotto-pattern vuoto. Probabilmente dovrebbe essere posizionato tra ( e :. Senza questo errore di battitura l'espressione sarà la stessa che si può trovare per il post type integrato 'page'.

jot jot
28 ott 2019 21:46:45
1

Ho avuto gli stessi problemi qui e lì e sembra non esserci alcun movimento sul sito WordPress. Nella mia situazione particolare, in cui per i singoli articoli del blog era necessaria la struttura /blog/%postname%/, questa soluzione

https://kellenmace.com/remove-custom-post-type-slug-from-permalinks/

ha prodotto una serie di errori 404

Ma insieme a questo meraviglioso approccio, che non utilizza la struttura dei permalink del backend per l'articolo del blog, alla fine funziona perfettamente. https://www.bobz.co/add-blog-prefix-permalink-structure-blog-posts/

Grazie mille.

19 giu 2019 18:39:51
Commenti

Le risposte costituite solo da link sono sconsigliate. Se hai trovato in questo articolo una risposta diversa dalle altre presenti nella pagina, per favore inserisci un riassunto e un esempio di codice nella tua risposta.

squarecandy squarecandy
17 dic 2019 00:50:24
2

Per me ha funzionato ora:

'rewrite' => array( 
'slug' => '/',
'with_front' => false
)

Inserisci all'interno della funzione register_post_type().

14 dic 2020 22:37:29
Commenti

Questa soluzione rompe le pagine semplici

mihdan mihdan
23 giu 2021 17:36:13

Ho provato e ha funzionato.

Questo è il codice semplice che devi utilizzare

register_post_type('wporg_product', array( 'labels' => array( 'name' => 'Portfolio', 'singular_name' => 'Portfolio', ), 'menu_icon' => 'dashicons-id', 'rewrite' => array( 'slug' => 'portfolio', 'with_front' => false ), // il mio slug personalizzato

        )
    );

Dopo aver modificato questo codice, devi salvare le impostazioni dei permalink una volta.

Rohit Rohit
4 ago 2024 11:38:03
0

Questo è ciò che ha funzionato per me. Sostituisci podcast con lo slug del tuo CPT (Custom Post Type):

add_action('init', function () {
    register_post_type(
        'podcast',
        [
            'rewrite' => false,
        ]
    );
});

add_filter('post_type_link', function ($post_link, $post, $leavename) {
    if (isset($post->post_type) && $post->post_type === 'podcast') {
        $post_link = home_url($post->post_name);
    }

    return $post_link;
}, 10, 3);

add_action('init', function () {
    add_rewrite_rule('(.+?)/?$', 'index.php?podcast=$matches[1]', 'bottom');
});
17 ago 2021 01:46:25
0

Il plugin "Remove CPT base" funziona.

https://wordpress.org/plugins/remove-cpt-base/

16 feb 2024 07:30:34
5
-1

Non è necessario scrivere così tanto codice hard-code. Basta utilizzare un plugin leggero:

Ha opzioni personalizzabili.

26 feb 2017 00:12:35
Commenti

Ora capisco perché sei stato downvotato, impedisce la risoluzione dei normali collegamenti alle pagine. Non l'avevo notato perché ottenevo copie memorizzate nella cache delle pagine esistenti nonostante il refresh.

Walf Walf
14 set 2017 05:36:54

@Walf Puoi spiegarmi il problema nei dettagli?

T.Todua T.Todua
14 set 2017 11:17:53

I collegamenti alle pagine (che non erano del custom post type) dal menu principale restituivano errori 404, come se la pagina non esistesse; tutto qui.

Walf Walf
14 set 2017 14:45:16

@Walf puoi darmi un esempio di URL del tuo caso? (puoi coprire il nome del dominio se vuoi, mi serve solo un esempio) grazie, lo aggiornerò

T.Todua T.Todua
15 set 2017 10:31:07

"Questo plugin è stato chiuso dal 19 settembre 2018 e non è più disponibile per il download. La chiusura è permanente."

squarecandy squarecandy
17 dic 2019 00:51:24