Usar register_post_type() para modificar un tipo de entrada existente
Hay muchas situaciones donde un tema o plugin registra un tipo de entrada y deseas modificarlo. Por supuesto existen add_post_type_support()
y remove_post_type_support()
, pero estos no dan acceso a la lista completa de argumentos que acepta register_post_type()
. En particular, tal vez quiero deshabilitar un archivo de tipo de entrada, ocultar la interfaz de administración, ocultar de la búsqueda, etc. mientras mantengo el resto de la configuración del tipo de entrada intacta.
La página del Codex para register_post_type()
me muestra esto:
Descripción
Crear o modificar un tipo de entrada.
Pero en el pasado, cuando he intentado hacer esto, no parece funcionar. ¿Esta función realmente sirve para modificar tipos de entrada, y si es así, se pueden simplemente redeclarar un par de argumentos y dejar el resto sin cambios?
Viendo que ni siquiera existe una función deregister_post_type()
, no entiendo cómo puede hacerse.

Después de investigar un poco, descubrí que ninguna de estas respuestas está actualizada.
A partir del 8 de diciembre de 2015, WordPress incluye un nuevo filtro, register_post_type_args
, que te permite enlazar con los argumentos de un tipo de entrada registrado.
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 );

¿Qué pasa si necesitas actualizarlo después de que se ha registrado en tiempo de ejecución? Por ejemplo: después de init

@LucasBustamante No importa. Solo llama la línea 'add_filter' durante tu plugin/tema, no en una acción. El filtro se llamará durante cada función register_post_type
. El único escenario donde mi código no funcionará es si el tipo de contenido no se está registrando correctamente. Todos los tipos de contenido deberían registrarse durante el hook init. Del codex: "register_post_type no funcionará si se llama antes de 'init', y aspectos del tipo de contenido recién creado o modificado funcionarán incorrectamente si se llama después." Si aún necesitas ayuda, sugiero publicar más detalles en una nueva pregunta.

Entonces, ¿este código cambiará el 'slug-del-post', como en 'sitioweb/proyectos/slug-del-post'??

@Krys No estoy seguro de lo que quieres decir, pero para aclarar: Si tienes "ejemplo.org/especies-animales/slug-del-post", te permite cambiar "especies-animales" a simplemente "animal" para que la URL quede como "ejemplo.org/animal/slug-del-post" y la página de archivo, si está habilitada, sería "ejemplo.org/animal/". Sin necesidad de cambiar el nombre del tipo de contenido.

¿Esta función es realmente para modificar tipos de post?
Sí.
y si es así, ¿puedes simplemente redeclarar un par de argumentos y dejar el resto sin cambios?
No. Si deseas modificar argumentos de un tipo de post, necesitas usar get_post_type_object
para obtener el objeto del tipo de post, modificar lo que quieras en él y luego registrarlo nuevamente usando tu tipo modificado como el nuevo parámetro $args.

¿Sería correcto hacer dos llamadas consecutivas con argumentos modificados al mismo register_post_type
? Supongo que sí por tu "Sí.", y no muestra ningún error y tiene el efecto deseado. El caso real es la segunda opción que presento en esta respuesta: http://wordpress.stackexchange.com/a/74331/12615

Sí, eso funciona, pero parece que si tienes que hacer eso, entonces necesitas agregar algunos filtros o algo más para evitar tener que registrar el mismo tipo de publicación una y otra vez. Básicamente, resuelve primero los argumentos y luego regístralo.

Aquí hay un ejemplo de cómo usar el filtro 'registered_post_type'
para modificar un tipo de contenido (post type) en otro plugin.
Un plugin que estaba usando no incluía un menu_icon en su definición, así que quise agregar uno propio.
<?php
/**
* Añade un icono de menú al CPT WP-VeriteCo Timeline
*
* El plugin de timeline no tiene un icono de menú, así que nos enganchamos a 'registered_post_type'
* y añadimos el nuestro.
*
* @param string $post_type el nombre del tipo de contenido
* @param object $args los argumentos del tipo de contenido
*/
function wpse_65075_modify_timeline_menu_icon( $post_type, $args ) {
// Asegurarnos de que solo editamos el tipo de contenido que queremos
if ( 'timeline' != $post_type )
return;
// Establecer icono de menú
$args->menu_icon = get_stylesheet_directory_uri() . '/img/admin/menu-timeline.png';
// Modificar el objeto del tipo de contenido
global $wp_post_types;
$wp_post_types[$post_type] = $args;
}
add_action( 'registered_post_type', 'wpse_65075_modify_timeline_menu_icon', 10, 2 );

Engánchate a 'registered_post_type'
después de que el otro código lo haya registrado. Se llama al final de register_post_type()
. Recibes dos argumentos: $post_type
y $args
.
Ahora puedes cambiar cualquier cosa para este tipo de contenido. Inspecciona $GLOBALS['wp_post_types']
para ver algunas opciones.

Gracias por señalarme ese hook. Eso responde a la pregunta (más importante) sobre cómo modificar un tipo de publicación, pero ¿qué pasa con la descripción de register_post_type()
que incluye "modificar"? ¿Eso es simplemente incorrecto? ¿Debería subirme a mi caballo de internet y eliminarlo del Codex en este momento?

Me pasó lo mismo con el plugin The Events Calendar.
Añadí el siguiente código a function.php para modificar el tipo de post tribe_organizer
function tribe_modify_organizer() {
//Nuevos argumentos
$tribe_organizer_args = get_post_type_object('tribe_organizer'); // obtener el tipo de post a modificar
$tribe_organizer_args-> taxonomies = array('post_tag' , 'tribe_events_cat'); // añadir soporte para taxonomías
$tribe_organizer_args-> exclude_from_search = false; // mostrar en resultados de búsqueda
//volver a registrar el mismo tipo de post incluyendo los nuevos argumentos
register_post_type( 'tribe_organizer', $tribe_organizer_args );
}
add_action( 'init', 'tribe_modify_organizer', 100 );

No sé si esto es feo, pero podrías alterar el marcador de posición GLOBAL
"sobre la marcha" cada vez que necesites manipular un solo argumento. Así es como usamos un tipo de publicación no público contents
para que sea aceptable en el menú de administración. Enganchamos justo antes y justo después de que se renderice el menú:
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);
En nuestro caso, queremos que el plugin Admin Menu Post List acepte nuestro tipo de publicación, ya que llaman return get_post_types(array('public' => true));
dentro de su enganche con prioridad 11...
Desarrolladores - Por favor, hagan un comentario si esto podría causar algún problema.
