Usa register_post_type() per modificare un tipo di post esistente
Ci sono molte situazioni in cui un tema o un plugin registra un tipo di post e si desidera modificarlo. Naturalmente esistono add_post_type_support()
e remove_post_type_support()
, ma questi non danno accesso all'elenco completo degli argomenti che register_post_type()
accetta. In particolare, potrei voler disabilitare l'archivio di un tipo di post, nascondere l'interfaccia di amministrazione, escludere dalla ricerca, ecc. mantenendo invariate le altre impostazioni del tipo di post.
La pagina del Codex per register_post_type()
mi mostra questo:
Descrizione
Crea o modifica un tipo di post.
Ma in passato, quando ho provato a farlo, non sembrava funzionare. Questa funzione serve davvero per modificare i tipi di post e, in tal caso, è possibile ridichiarare solo alcuni argomenti e lasciare il resto inalterato?
Considerando che non esiste nemmeno una funzione deregister_post_type()
, non capisco come possa essere fatto.

Dopo alcune ricerche ho scoperto che nessuna di queste risposte è aggiornata.
A partire dall'8 dicembre 2015 WordPress include un nuovo filtro, register_post_type_args
, che permette di intervenire sugli argomenti di un tipo di post registrato.
function wp1482371_custom_post_type_args( $args, $post_type ) {
if ( $post_type == "animal-species" ) {
$args['rewrite'] = array(
'slug' => 'animal'
);
}
return $args;
}
add_filter( 'register_post_type_args', 'wp1482371_custom_post_type_args', 20, 2 );

Cosa succede se hai bisogno di aggiornarlo dopo che è stato registrato in runtime? Ad esempio: dopo init

@LucasBustamante Non importa. Basta chiamare la linea 'add_filter' durante il tuo plugin/tema, non in un'azione. Il filtro verrà chiamato durante ogni funzione register_post_type
. L'unico scenario in cui il mio codice non funzionerà è se il post type non viene registrato correttamente. Tutti i post type dovrebbero essere registrati durante l'hook init. Dal codex: "register_post_type non funzionerà se chiamato prima di 'init', e alcuni aspetti del post type appena creato o modificato funzioneranno in modo errato se chiamati successivamente." Se hai ancora bisogno di aiuto, ti suggerisco di pubblicare maggiori dettagli in una nuova domanda.

quindi, questo codice cambierà lo 'slug-of-post', come in 'nomesito/progetti/slug-of-post' ??

@Krys Non sono sicuro di cosa intendi, ma per chiarire: Se hai "example.org/animal-species/slug-of-post", ti permette di cambiare "animal-species" in semplicemente "animal" così l'URL diventerebbe "example.org/animal/slug-of-post" e la pagina archivio, se abilitata, sarebbe "example.org/animal/". Senza bisogno di cambiare il nome del post type.

Questa funzione serve davvero a modificare i tipi di post?
Sì.
Se è così, posso semplicemente ridefinire un paio di argomenti e lasciare il resto invariato?
No. Se vuoi modificare gli argomenti di un tipo di post, devi usare get_post_type_object
per ottenere l'oggetto del tipo di post, modificare ciò che vuoi al suo interno, quindi registrarlo nuovamente utilizzando il tuo tipo modificato come nuovo parametro $args.

Sarebbe corretto effettuare due chiamate consecutive con argomenti modificati alla stessa funzione register_post_type
? Presumo di sì dal tuo "Sì.", e non genera errori e ha l'effetto desiderato. Il caso reale è la seconda opzione che presento in questa risposta: http://wordpress.stackexchange.com/a/74331/12615

Sì, funziona, ma sembra che se devi fare così, allora dovresti aggiungere alcuni filtri o qualcos'altro per evitare di dover registrare ripetutamente lo stesso tipo di post più e più volte. In sostanza, sistema prima gli argomenti, poi registralo.

Ecco un esempio di come utilizzare il filtro 'registered_post_type'
per modificare un tipo di post in un altro plugin.
Un plugin che stavo utilizzando non includeva un menu_icon nella sua definizione, quindi ho voluto aggiungerne uno personalizzato.
<?php
/**
* Aggiunge un'icona al menu per il CPT WP-VeriteCo Timeline
*
* Il plugin timeline non ha un'icona per il menu, quindi agganciamo 'registered_post_type'
* e aggiungiamo la nostra.
*
* @param string $post_type il nome del tipo di post
* @param object $args gli argomenti del tipo di post
*/
function wpse_65075_modify_timeline_menu_icon( $post_type, $args ) {
// Assicuriamoci di modificare solo il tipo di post desiderato
if ( 'timeline' != $post_type )
return;
// Imposta l'icona del menu
$args->menu_icon = get_stylesheet_directory_uri() . '/img/admin/menu-timeline.png';
// Modifica l'oggetto del tipo di post
global $wp_post_types;
$wp_post_types[$post_type] = $args;
}
add_action( 'registered_post_type', 'wpse_65075_modify_timeline_menu_icon', 10, 2 );

Agganciati a 'registered_post_type'
dopo che il codice lo ha registrato. Viene chiamato alla fine di register_post_type()
. Ricevi due argomenti: $post_type
e $args
.
Ora puoi modificare qualsiasi cosa per questo post type. Esamina $GLOBALS['wp_post_types']
per vedere alcune opzioni.

Grazie per avermi indirizzato verso quell'hook. Questo risponde alla domanda (più importante) su come modificare un post type, ma riguardo alla descrizione di register_post_type()
che include "modify"? È semplicemente sbagliata? Dovrei saltare sul mio cavallo internet e cancellarla immediatamente dal Codex?

Ho affrontato lo stesso problema con il plugin The Events Calendar.
Ho aggiunto il seguente codice al file function.php per modificare il post type tribe_organizer
function tribe_modify_organizer() {
// Nuovi argomenti
$tribe_organizer_args = get_post_type_object('tribe_organizer'); // ottieni il post type da modificare
$tribe_organizer_args-> taxonomies = array('post_tag' , 'tribe_events_cat'); // aggiungi supporto alle tassonomie
$tribe_organizer_args-> exclude_from_search = false; // mostra nei risultati di ricerca
// ri-registra lo stesso post type includendo i nuovi argomenti
register_post_type( 'tribe_organizer', $tribe_organizer_args );
}
add_action( 'init', 'tribe_modify_organizer', 100 );

Non so se sia brutto, ma potresti modificare il segnaposto GLOBAL
"al volo" ogni volta che devi manipolare un singolo argomento. Ecco come utilizziamo un tipo di post non pubblico contents
per renderlo accettabile nel menu di amministrazione. Agganciamo le funzioni appena prima e appena dopo il rendering del menu:
function entex_theme_make_contents_public(){
$GLOBALS['wp_post_types']['contents']->public = true;
}
add_action('admin_menu', 'entex_theme_make_contents_public', 10);
function entex_theme_make_contents_private_again(){
$GLOBALS['wp_post_types']['contents']->public = '';
}
add_action('admin_menu', 'entex_theme_make_contents_private_again', 12);
Nel nostro caso, vogliamo che il plugin Admin Menu Post List accetti il nostro tipo di post, poiché chiamano return get_post_types(array('public' => true));
all'interno del loro hook con priorità 11...
Sviluppatori - Per favore, lasciate un commento se questo potrebbe causare problemi.
