Aggiungere categorie al tipo di post personalizzato nel permalink
So che le persone hanno già fatto questa domanda e sono arrivate fino all'aggiunta del tipo di post personalizzato e alla riscrittura del permalink.
Il problema è che ho 340 categorie esistenti che vorrei continuare ad utilizzare. Prima potevo vedere /categoria/sottocategoria/nome-post
Ora ho lo slug del tipo di post personalizzato/nome-post. La selezione della categoria non appare più nel permalink... Non ho modificato le impostazioni del permalink nell'amministrazione.
C'è qualcosa che mi sfugge o che devo aggiungere a questo codice?
function jcj_club_post_types() {
register_post_type( 'jcj_club', array(
'labels' => array(
'name' => __( 'Club Jazz' ),
'singular_name' => __( 'Club Jazz' ),
'add_new' => __( 'Aggiungi Nuovo' ),
'add_new_item' => __( 'Aggiungi Nuovo Club Jazz' ),
'edit' => __( 'Modifica' ),
'edit_item' => __( 'Modifica Club Jazz' ),
'new_item' => __( 'Nuovo Club Jazz' ),
'view' => __( 'Visualizza Club Jazz' ),
'view_item' => __( 'Visualizza Club Jazz' ),
'search_items' => __( 'Cerca Club Jazz' ),
'not_found' => __( 'Nessun club jazz trovato' ),
'not_found_in_trash' => __( 'Nessun club jazz trovato nel Cestino' ),
'parent' => __( 'Club Jazz Genitore' ),
),
'public' => true,
'show_ui' => true,
'publicly_queryable' => true,
'exclude_from_search' => false,
'menu_position' => 5,
'query_var' => true,
'supports' => array(
'title',
'editor',
'comments',
'revisions',
'trackbacks',
'author',
'excerpt',
'thumbnail',
'custom-fields',
),
'rewrite' => array( 'slug' => 'jazz-clubs-in', 'with_front' => true ),
'taxonomies' => array( 'category','post_tag'),
'can_export' => true,
)
);
Ci sono 2 punti di attacco da coprire quando si aggiungono regole di rewrite per i custom post type:
Regole di rewrite
Questo accade quando le regole di rewrite vengono generate in wp-includes/rewrite.php
nella funzione WP_Rewrite::rewrite_rules()
. WordPress ti permette di filtrare le regole di rewrite per elementi specifici come post, pagine e vari tipi di archivio. Dove vedi posttype_rewrite_rules
la parte posttype
dovrebbe essere il nome del tuo custom post type. In alternativa puoi usare il filtro post_rewrite_rules
purché non sovrascrivi anche le regole standard dei post.
Poi abbiamo bisogno della funzione che genera effettivamente le regole di rewrite:
// aggiungiamo il nostro nuovo permastruct alle regole di rewrite
add_filter( 'posttype_rewrite_rules', 'add_permastruct' );
function add_permastruct( $rules ) {
global $wp_rewrite;
// imposta qui la struttura dei permalink che desideri
$struct = '/%category%/%year%/%monthnum%/%postname%/';
// usa la funzione di generazione delle regole di rewrite di WP
$rules = $wp_rewrite->generate_rewrite_rules(
$struct, // la struttura del permalink
EP_PERMALINK, // Maschera endpoint: aggiunge regole per endpoint di singoli post come pagine di commenti etc...
false, // Paged: aggiunge regole per l'impaginazione (non necessario qui)
true, // Feed: aggiunge regole per gli endpoint dei feed
true, // Per i commenti: se le regole dei feed dovrebbero essere per i commenti del post - su una pagina singola aggiunge endpoint per i feed dei commenti
false, // Walk directories: se generare regole per ogni segmento del permastruct delimitato da '/'. Impostare sempre su false altrimenti le regole personalizzate saranno troppo "greedy" e appariranno in cima alle regole
true // Aggiungi endpoint personalizzati
);
return $rules;
}
La cosa principale a cui fare attenzione se decidi di sperimentare è il parametro booleano 'Walk directories'. Genera regole di rewrite per ogni segmento di un permastruct e può causare mancati match nelle regole di rewrite. Quando viene richiesto un URL di WordPress, l'array delle regole di rewrite viene controllato dall'alto verso il basso. Non appena viene trovato un match, caricherà qualunque cosa abbia trovato, quindi per esempio se il tuo permastruct ha un match "greedy" come /%category%/%postname%/
e walk directories è attivo, genererà regole di rewrite sia per /%category%/%postname%/
CHE per /%category%/
che farà match con qualsiasi cosa. Se ciò accade troppo presto, sei fregato.
Permalink
Questa è la funzione che analizza i permalink del post type e converte un permastruct (es. '/%year%/%monthnum%/%postname%/') in un URL reale.
La parte seguente è un semplice esempio di ciò che idealmente sarebbe una versione della funzione get_permalink()
che si trova in wp-includes/link-template.php
. I permalink personalizzati dei post sono generati da get_post_permalink()
che è una versione molto semplificata di get_permalink()
. get_post_permalink()
viene filtrato da post_type_link
quindi lo useremo per creare una struttura personalizzata.
// analizza i link generati
add_filter( 'post_type_link', 'custom_post_permalink', 10, 4 );
function custom_post_permalink( $permalink, $post, $leavename, $sample ) {
// esegui le nostre modifiche solo se stiamo usando permalink "pretty"
// e se è il nostro post type target
if ( $post->post_type == 'posttype' && get_option( 'permalink_structure' ) ) {
// ricordiamo la nostra struttura di permalink desiderata qui
// dobbiamo generare l'equivalente con dati reali
// per far match con le regole di rewrite impostate prima
$struct = '/%category%/%year%/%monthnum%/%postname%/';
$rewritecodes = array(
'%category%',
'%year%',
'%monthnum%',
'%postname%'
);
// prepariamo i dati
$terms = get_the_terms($post->ID, 'category');
$unixtime = strtotime( $post->post_date );
// questo codice viene da get_permalink()
$category = '';
if ( strpos($permalink, '%category%') !== false ) {
$cats = get_the_category($post->ID);
if ( $cats ) {
usort($cats, '_usort_terms_by_ID'); // ordina per ID
$category = $cats[0]->slug;
if ( $parent = $cats[0]->parent )
$category = get_category_parents($parent, false, '/', true) . $category;
}
// mostra la categoria di default nei permalink, senza
// doverla assegnare esplicitamente
if ( empty($category) ) {
$default_category = get_category( get_option( 'default_category' ) );
$category = is_wp_error( $default_category ) ? '' : $default_category->slug;
}
}
$replacements = array(
$category,
date( 'Y', $unixtime ),
date( 'm', $unixtime ),
$post->post_name
);
// completiamo il permalink
$permalink = home_url( str_replace( $rewritecodes, $replacements, $struct ) );
$permalink = user_trailingslashit($permalink, 'single');
}
return $permalink;
}
Come detto, questo è un caso molto semplificato per generare un set personalizzato di regole di rewrite e permalink, e non è particolarmente flessibile ma dovrebbe essere sufficiente per iniziare.
Trucchetto
Ho scritto un plugin che ti permette di definire permastruct per qualsiasi custom post type, ma come puoi usare %category%
nella struttura dei permalink per i post, il mio plugin supporta %custom_taxonomy_name%
per qualsiasi tassonomia personalizzata tu abbia, dove custom_taxonomy_name
è il nome della tua tassonomia es. %club%
.
Funzionerà come ti aspetteresti con tassonomie gerarchiche/non gerarchiche.

il plugin è fantastico, ma potresti spiegare come risolvere il problema nella domanda senza il tuo plugin?

Concordo che è fantastico che esista un plugin per risolverlo (l'ho aggiunto ai preferiti ed è la prima cosa che mi è venuta in mente su questa domanda), ma la risposta trarrebbe beneficio da un breve riassunto di quale sia il problema e come il plugin lo ha risolto. :)

@EugeneManuilov Va bene, scusa se è una risposta lunga. E questo dopo averla ridotta all'essenziale!

Sembra che il primo $permalink = home_url(...
venga sovrascritto da $permalink = user_trailingslashit(...
e non venga mai utilizzato. O mi sto perdendo qualcosa? $post_link
non è nemmeno definito. Sarebbe dovuto essere $permalink = user_trailingslashit( $permalink, 'single' );
?

Ottima osservazione, dovrebbe essere $permalink
non $post_link
. Grazie :)

HO TROVATO UNA SOLUZIONE!!!
(Dopo infinite ricerche.. posso avere i permalink per CUSTOM POST TYPE come:
example.com/categoria/sottocategoria/nome-del-mio-post
ecco il codice (in functions.php o in un plugin):
//===PASSO 1 (interessa solo questi CUSTOM POST TYPE)
$GLOBALS['my_post_typesss__MLSS'] = array('my_product1','....');
//===PASSO 2 (crea i PERMALINK desiderati)
add_filter('post_type_link', 'my_func88888', 6, 4 );
function my_func88888( $post_link, $post, $sdsd){
if (!empty($post->post_type) && in_array($post->post_type, $GLOBALS['my_post_typesss']) ) {
$SLUGG = $post->post_name;
$post_cats = get_the_category($id);
if (!empty($post_cats[0])){ $target_CAT= $post_cats[0];
while(!empty($target_CAT->slug)){
$SLUGG = $target_CAT->slug .'/'.$SLUGG;
if (!empty($target_CAT->parent)) {$target_CAT = get_term( $target_CAT->parent, 'category');} else {break;}
}
$post_link= get_option('home').'/'. urldecode($SLUGG);
}
}
return $post_link;
}
// PASSO 3 (di default, quando si accede a: "EXAMPLE.COM/categoria/nomepost"
// WP pensa che venga richiesto un post standard. Quindi, aggiungiamo i CUSTOM POST
// TYPE a quella query.
add_action('pre_get_posts', 'my_func4444', 12);
function my_func4444($q){
if ($q->is_main_query() && !is_admin() && $q->is_single){
$q->set( 'post_type', array_merge(array('post'), $GLOBALS['my_post_typesss'] ) );
}
return $q;
}

Trovata 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. 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 Help Center Trovato'),
'not_found_in_trash' => __('Nessun Articolo Help Center 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 fa funzionare il tuo permalink
"cptp_permalink_structure" => "/%help_centre_category%/%post_id%-%postname%/",
puoi rimuovere %post_id%
e mantenere /%help_centre_category%/%postname%/"
Non dimenticare di ripulire i permalink dalla dashboard.

+1 la soluzione più semplice è usare questo plugin: https://wordpress.org/plugins/custom-post-type-permalinks/ funziona perfettamente

Hai diversi errori nel tuo codice. Ho ripulito il codice esistente:
<?php
function jcj_club_post_types() {
$labels = array(
'name' => __( 'Jazz Clubs' ),
'singular_name' => __( 'Jazz Club' ),
'add_new' => __( 'Aggiungi nuovo' ),
'add_new_item' => __( 'Aggiungi nuovo Jazz Club' ),
'edit' => __( 'Modifica' ),
'edit_item' => __( 'Modifica Jazz Club' ),
'new_item' => __( 'Nuovo Jazz Club' ),
'view' => __( 'Visualizza Jazz Club' ),
'view_item' => __( 'Visualizza Jazz Club' ),
'search_items' => __( 'Cerca Jazz Club' ),
'not_found' => __( 'Nessun jazz club trovato' ),
'not_found_in_trash' => __( 'Nessun jazz club trovato nel cestino' ),
'parent' => __( 'Jazz Club genitore' ),
);
$args = array(
'public' => true,
'show_ui' => true,
'publicly_queryable' => true,
'exclude_from_search' => false,
'menu_position' => 5,
'query_var' => true,
'supports' => array( 'title','editor','comments','revisions','trackbacks','author','excerpt','thumbnail','custom-fields' ),
'rewrite' => array( 'slug' => 'jazz-clubs-in', 'with_front' => true ),
'has_archive' => true
);
register_post_type( 'jcj_club', $args );
}
add_action( 'init','jcj_club_post_types' );
?>
Sostituisci il tuo codice con il codice qui sopra e verifica se funziona. Rispondimi se hai ulteriori domande e cercherò di aiutarti.
MODIFICA:
Ho notato che avevo omesso 'has_archive' => true
.
