Aggiungere la base della categoria all'URL in un custom post type/tassonomia

6 apr 2013, 18:59:28
Visualizzazioni: 127K
Voti: 45

Sto costruendo un sistema tipo LMS in WordPress, controllato da Custom Post Type. Il post type si chiama Lessons (con uno slug di courses) e ha una tassonomia personalizzata (categoria) chiamata courses.

La struttura URL del dominio mostra attualmente:

domain.example/courses/lesson-name.

Voglio che diventi:

domain.example/courses/[course-name{categoria}]/lesson-name

o essenzialmente:

/[cpt]/%category%/%postname%/

Ecco il plugin che ho scritto che sta controllando i CPT ora.

function rflms_post_type() {
    $labels = array(
        'name'                => _x( 'Lezioni', 'Nome Generale Tipo Post', 'text_domain' ),
        'singular_name'       => _x( 'Lezione', 'Nome Singolare Tipo Post', 'text_domain' ),
        'menu_name'           => __( 'Lezioni', 'text_domain' ),
        'parent_item_colon'   => __( 'Prodotto Genitore:', 'text_domain' ),
        'all_items'           => __( 'Tutte le Lezioni', 'text_domain' ),
        'view_item'           => __( 'Visualizza Lezione', 'text_domain' ),
        'add_new_item'        => __( 'Aggiungi Nuova Lezione', 'text_domain' ),
        'add_new'             => __( 'Nuova Lezione', 'text_domain' ),
        'edit_item'           => __( 'Modifica Lezione', 'text_domain' ),
        'update_item'         => __( 'Aggiorna Lezione', 'text_domain' ),
        'search_items'        => __( 'Cerca Lezioni', 'text_domain' ),
        'not_found'           => __( 'Nessuna Lezione Trovata', 'text_domain' ),
        'not_found_in_trash'  => __( 'Nessuna Lezione Trovata nel Cestino', 'text_domain' ),
    );

    $args = array(
        'label'               => __( 'Lezioni', 'text_domain' ),
        'description'         => __( 'Lezioni Referenziabili', 'text_domain' ),
        'labels'              => $labels,
        'hierarchical'        => false,
        'public'              => true,
        'show_ui'             => true,
        'show_in_menu'        => true,
        'show_in_nav_menus'   => true,
        'show_in_admin_bar'   => true,
        'supports'        => array('premise-member-access', 'title', 'editor', 'author', 'thumbnail', 'excerpt', 'comments'),
        'menu_position'       => 5,
        'menu_icon'           => null,
        'can_export'          => true,
        'has_archive'         => true,
        'exclude_from_search' => false,
        'publicly_queryable'  => true,
        'capability_type'     => 'post',
        'rewrite'                    => array('slug' => 'courses'),
    );

    register_post_type( 'lessons', $args );

// Aggancio all'azione 'init'

}
add_action( 'init', 'rflms_post_type', 0 );

// Registra Tassonomia Personalizzata
function custom_taxonomy()  {
    $labels = array(
        'name'                       => _x( 'Corsi', 'Nome Generale Tassonomia', 'text_domain' ),
        'singular_name'              => _x( 'Corso', 'Nome Singolare Tassonomia', 'text_domain' ),
        'menu_name'                  => __( 'Corsi', 'text_domain' ),
        'all_items'                  => __( 'Tutti i Corsi', 'text_domain' ),
        'parent_item'                => __( 'Corso Genitore', 'text_domain' ),
        'parent_item_colon'          => __( 'Corso Genitore:', 'text_domain' ),
        'new_item_name'              => __( 'Nome Nuovo Corso', 'text_domain' ),
        'add_new_item'               => __( 'Aggiungi Nuovo Corso', 'text_domain' ),
        'edit_item'                  => __( 'Modifica Corso', 'text_domain' ),
        'update_item'                => __( 'Aggiorna Corso', 'text_domain' ),
        'separate_items_with_commas' => __( 'Separa i Corsi con virgole', 'text_domain' ),
        'search_items'               => __( 'Cerca Corsi', 'text_domain' ),
        'add_or_remove_items'        => __( 'Aggiungi o Rimuovi Corsi', 'text_domain' ),
        'choose_from_most_used'      => __( 'Scegli tra i Corsi più usati', 'text_domain' ),
    );

    $args = array(
        'labels'                     => $labels,
        'hierarchical'               => true,
        'public'                     => true,
        'show_ui'                    => true,
        'show_admin_column'          => true,
        'show_in_nav_menus'          => true,
        'show_tagcloud'              => false,
        'rewrite'                    => array('slug' => 'courses'),
    );

    register_taxonomy( 'course', 'lessons', $args );
}

// Aggancio all'azione 'init'
add_action( 'init', 'custom_taxonomy', 0 );
3
Commenti

Recentemente ho affrontato questo problema. Risolto! #188834

maheshwaghmare maheshwaghmare
20 mag 2015 10:03:35

SOLUZIONE! (Dopo infinite ricerche)<br/><br/>dovresti modificare il filtro post_type_link. maggiori informazioni su: http://wordpress.stackexchange.com/a/167992/33667 )

T.Todua T.Todua
26 lug 2015 23:06:09
Tutte le risposte alla domanda 9
10
63

Modifica il tuo rewrite per aggiungere la variabile di query del corso:

'rewrite' => array('slug' => 'courses/%course%')

Poi filtra post_type_link per inserire il corso selezionato nel permalink:

function wpa_course_post_link( $post_link, $id = 0 ){
    $post = get_post($id);  
    if ( is_object( $post ) ){
        $terms = wp_get_object_terms( $post->ID, 'course' );
        if( $terms ){
            return str_replace( '%course%' , $terms[0]->slug , $post_link );
        }
    }
    return $post_link;  
}
add_filter( 'post_type_link', 'wpa_course_post_link', 1, 3 );

Esistono anche plugin come Custom Post Type Permalinks che possono fare questo per te.

6 apr 2013 19:12:34
Commenti

Grazie, apprezzo la tua rapida risposta. Ha perfettamente senso. Sono comunque curioso, dove devo inserire il filtro post_type_link? Posso semplicemente metterlo in fondo all'intero documento?

Zach Russell Zach Russell
6 apr 2013 19:26:26

L'ho aggiunto in fondo ma la pagina restituisce errore 404.

Zach Russell Zach Russell
6 apr 2013 19:31:39

devi eseguire il flush delle rewrite rules, visita la pagina delle impostazioni dei permalink.

Milo Milo
6 apr 2013 20:09:58

nota anche che è probabile che ci sia un conflitto tra una tassonomia e un tipo di post che condividono lo stesso slug.

Milo Milo
6 apr 2013 20:13:20

Ora il punto in cui mi trovo è che sta generando i permalink correttamente, ma non li esegue come dovrebbe (restituisce un soft 404). Hai qualche consiglio su cosa posso fare per far funzionare tutto correttamente? Sono consapevole del flush dei rewrite dei permalink. Basta cliccare 'salva' e aggiorna il file (è nginx quindi è controllato nel file nginx.conf)

Zach Russell Zach Russell
6 apr 2013 20:29:46

Risolto! Era un conflitto.

Zach Russell Zach Russell
6 apr 2013 20:37:28

Voto negativo - pagina archivio 404

Brad Dalton Brad Dalton
4 apr 2020 04:06:27

Questo non funziona per i post tradotti su un sito multilingue (ad esempio utilizzando WPML).

montrealist montrealist
5 ago 2020 16:40:05

Questo mostra la pagina principale per me sul nuovo URL creato. Devi utilizzare add_rewrite_rule() come visto nella risposta di @Floris per farlo funzionare. Inoltre, nota che le pagine di archivio smettono di funzionare, ottengo 404 per /my-post-type e per /my-post-type/my-category

trainoasis trainoasis
1 set 2020 10:16:49

Questo mostrerà il post indipendentemente dallo slug del corso. Viene visualizzato su TUTTI gli slug dei corsi. Come limitarlo in modo che venga mostrato solo sullo slug del corso selezionato e restituisca un 404 per i corsi che non sono selezionati per quella persona?

Solomon Closson Solomon Closson
16 giu 2021 01:27:23
Mostra i restanti 5 commenti
0
11

La soluzione per me ha avuto tre parti. Nel mio caso il post type si chiama trainings.

  1. Aggiungi 'rewrite' => array('slug' => 'trainings/%cat%') alla funzione register_post_type.
  2. Modifica lo slug per avere una categoria dinamica.
  3. "Ascolta" il nuovo URL dinamico e carica il template appropriato.

Ecco come modificare dinamicamente il permalink per un determinato post type. Aggiungi a functions.php:

function vx_soon_training_post_link( $post_link, $id = 0 ) {
    $post = get_post( $id );
    if ( is_object( $post ) ) {
        $terms = wp_get_object_terms( $post->ID, 'training_cat' );
        if ( $terms ) {
            return str_replace( '%cat%', $terms[0]->slug, $post_link );
        }
    }

    return $post_link;
}

add_filter( 'post_type_link', 'vx_soon_training_post_link', 1, 3 );

...e questo è come caricare il template appropriato sul nuovo URL dinamico. Aggiungi a functions.php:

function archive_rewrite_rules() {
    add_rewrite_rule(
        '^training/(.*)/(.*)/?$',
        'index.php?post_type=trainings&name=$matches[2]',
        'top'
    );
    //flush_rewrite_rules(); // usare solo una volta
}

add_action( 'init', 'archive_rewrite_rules' );

Questo è tutto! Ricordati di aggiornare i permalink salvandoli nuovamente nel backend. Oppure usa la funzione flush_rewrite_rules().

11 feb 2019 13:15:23
0

Ho trovato la soluzione!

Per avere permalink gerarchici per i custom post type installa il plugin Custom Post Type Permalinks(https://wordpress.org/plugins/custom-post-type-permalinks/).

Aggiorna il post type registrato. Io ho un post type chiamato help center

function help_centre_post_type(){
    register_post_type('helpcentre', array( 
        'labels'            =>  array(
            'name'          =>      __('Help Center'),
            'singular_name' =>      __('Help Center'),
            'all_items'     =>      __('Visualizza Articoli'),
            'add_new'       =>      __('Nuovo Articolo'),
            'add_new_item'  =>      __('Nuovo Help Center'),
            'edit_item'     =>      __('Modifica Help Center'),
            'view_item'     =>      __('Vedi Help Center'),
            'search_items'  =>      __('Cerca Help Center'),
            'no_found'      =>      __('Nessun Articolo Trovato'),
            'not_found_in_trash' => __('Nessun Articolo nel Cestino')
                                ),
        'public'            =>  true,
        'publicly_queryable'=>  true,
        'show_ui'           =>  true, 
        'query_var'         =>  true,
        'show_in_nav_menus' =>  false,
        'capability_type'   =>  'page',
        'hierarchical'      =>  true,
        'rewrite'=> [
            'slug' => 'help-center',
            "with_front" => false
        ],
        "cptp_permalink_structure" => "/%help_centre_category%/%post_id%-%postname%/",
        'menu_position'     =>  21,
        'supports'          =>  array('title','editor', 'thumbnail'),
        'has_archive'       =>  true
    ));
    flush_rewrite_rules();
}
add_action('init', 'help_centre_post_type');

Ed ecco la tassonomia registrata

function themes_taxonomy() {  
    register_taxonomy(  
        'help_centre_category',  
        'helpcentre',        
        array(
            'label' => __( 'Categorie' ),
            'rewrite'=> [
                'slug' => 'help-center',
                "with_front" => false
            ],
            "cptp_permalink_structure" => "/%help_centre_category%/",
            'hierarchical'               => true,
            'public'                     => true,
            'show_ui'                    => true,
            'show_admin_column'          => true,
            'show_in_nav_menus'          => true,
            'query_var' => true
        ) 
    );  
}  
add_action( 'init', 'themes_taxonomy');

Questa riga rende funzionanti i tuoi permalink

"cptp_permalink_structure" => "/%help_centre_category%/%post_id%-%postname%/",

Puoi rimuovere %post_id% e tenere /%help_centre_category%/%postname%/"

Non dimenticare di svuotare i permalink dalla dashboard.

6 ott 2017 14:39:43
2

Devi aggiornare la riga dove hai registrato un custom post type utilizzando la funzione register_post_type.

'rewrite' => array('slug' => 'courses/%cat%')

Per cambiare dinamicamente il permalink del post type, devi aggiungere questo codice nel file functions.php:

function change_link( $post_link, $id = 0 ) {
    $post = get_post( $id );
    if( $post->post_type == 'courses' )
    {
       if ( is_object( $post ) ) {
          $terms = wp_get_object_terms( $post->ID, array('course') );
          if ( $terms ) {
             return str_replace( '%cat%', $terms[0]->slug, $post_link );
         }
      }
    }
    return   $post_link ;
}
add_filter( 'post_type_link', 'change_link', 1, 3 );

//carica il template sul nuovo URL generato altrimenti otterrai errori 404

function generated_rewrite_rules() {
   add_rewrite_rule(
       '^courses/(.*)/(.*)/?$',
       'index.php?post_type=courses&name=$matches[2]',
       'top'
   );
}
add_action( 'init', 'generated_rewrite_rules' );

Dopodiché, devi ripulire i permalink riscritti. Vai su wp-admin > Impostazioni > permalink e aggiorna le impostazioni dei permalink poi premi il pulsante "Salva modifiche". Genererà URL come questo: dominio.esempio/courses/[nome-corso{categoria}]/nome-lezione

12 giu 2019 16:21:01
Commenti

Voto negativo - Errore 404 sia sulle pagine singole CPT che sugli archivi CTP

Brad Dalton Brad Dalton
4 apr 2020 04:07:21

@dev hai seguito tutti i passaggi che ho menzionato nella mia risposta? Hai resettato i permalink rewrite? Ho testato e funziona correttamente.

Chetan Vaghela Chetan Vaghela
4 apr 2020 06:57:55
0

Per chiunque sia interessato alla soluzione, senza dover pasticciare con codice PHP grezzo, consiglio vivamente il plugin Permalink Manager Lite di Maciej Bis. È un salva-vita.

Dispone di un meccanismo visivo per rimuovere o aggiungere qualsiasi parte desiderata nell'URL dei custom post type basato sui 'permastruct':

Schermata di Permalink Manager Lite

(Con tutta la fatica coinvolta nella semplice strutturazione degli URL con i custom post type, stavamo per abbandonare WP e passare a un altro CMS. Ma questo plugin, insieme ad ACF e CPTUI o Pods, rende Wordpress abbastanza professionale.)

1 lug 2019 06:50:24
0

Sì! Dopo molte ricerche ho trovato il plugin 'Custom Permalinks'. Che soddisfa la mia esigenza riguardo agli URL personalizzati, ad esempio:

  • per le Categorie
  • per gli Articoli
  • per i Custom Post
  • per le Tassonomie Personalizzate ecc.

Come questo Custom Post Type - Post:

Plugin Custom Permalinks per WordPress

20 mag 2015 09:59:41
1

Questo ha funzionato per me:

'rewrite' => array(
        'slug' => 'portfolio', // slug per i permalinks
        'with_front' => false, // esclude il prefisso dallo slug
        'hierarchical' => true // per visualizzare categorie/sottocategorie
    ),
3 mag 2017 20:17:57
Commenti

Questo non utilizza le categorie o il loro percorso, rende solo il custom post type gerarchico.

Joris Kroos Joris Kroos
25 ago 2017 14:53:22
0

Se stai utilizzando get_post_type_archive_link(), potresti aver bisogno di rimuovere /%cat%/ dall'URL utilizzando il filtro post_type_archive_link.

29 mag 2020 19:33:42
0

Ho trovato la risposta di @chetan-vaghela quasi perfetta; nel mio caso d'uso volevo anche poter vedere un elenco di tutti i post di questo tipo di contenuto come una tipica pagina archivio (es. /corsi/, senza alcuna tassonomia dopo). Ho dovuto solo aggiungere una regola di riscrittura aggiuntiva come segue:

function generated_rewrite_rules() {
    add_rewrite_rule(
        '^corsi/(.*)/(.*)/?$',
        'index.php?post_type=courses&name=$matches[2]',
        'top'
    );
}
18 ago 2020 13:07:15