Agregar columnas personalizadas a tipos de contenido personalizados
He hecho esto anteriormente pero he olvidado el nombre del hook y no puedo encontrarlo en ningún lado...
Lo que estoy tratando de hacer es agregar algunas columnas personalizadas en el listado de un tipo de contenido personalizado en el admin.
Por ejemplo, en el admin, al hacer clic en artículos, quiero agregar una columna personalizada allí.
Los hooks para crear columnas personalizadas y sus datos asociados para un tipo de publicación personalizada son manage_{$post_type}_posts_columns
y manage_{$post_type}_posts_custom_column
respectivamente, donde {$post_type}
es el nombre del tipo de publicación personalizada.
Este ejemplo de la documentación elimina la columna del autor y añade una columna de taxonomía y metadatos:
// Añade las columnas personalizadas al tipo de publicación 'book':
add_filter( 'manage_book_posts_columns', 'set_custom_edit_book_columns' );
function set_custom_edit_book_columns($columns) {
unset( $columns['author'] );
$columns['book_author'] = __( 'Autor', 'your_text_domain' );
$columns['publisher'] = __( 'Editorial', 'your_text_domain' );
return $columns;
}
// Añade los datos a las columnas personalizadas para el tipo de publicación 'book':
add_action( 'manage_book_posts_custom_column' , 'custom_book_column', 10, 2 );
function custom_book_column( $column, $post_id ) {
switch ( $column ) {
case 'book_author' :
$terms = get_the_term_list( $post_id , 'book_author' , '' , ',' , '' );
if ( is_string( $terms ) )
echo $terms;
else
_e( 'No se pudo obtener el/los autor(es)', 'your_text_domain' );
break;
case 'publisher' :
echo get_post_meta( $post_id , 'publisher' , true );
break;
}
}

¡¡¡Gracias por este hook!!! ¡¡Es brillante!! No hay documentación clara en stackoverflow!!! :D ¡Saludos colega!

¿No hay alguna opción para establecer el número de columna? como column_index[2]
. Porque la custom_column aparece al final de la columna.

En el caso de agregar una columna de términos de taxonomía. ¿Cómo agregarías un enlace debajo del nombre del término que filtraría la tabla por ese término? He visto esto en algunos plugins antes.

@iamonstage register_taxonomy()
ahora tiene soporte integrado para eso a través del parámetro show_admin_column
que se pasa mediante los argumentos. https://developer.wordpress.org/reference/functions/register_taxonomy/. Si no estás registrando la taxonomía tú mismo, aún puedes modificar los argumentos mediante el filtro register_taxonomy_args
https://developer.wordpress.org/reference/hooks/register_taxonomy_args/

Escribí una función que combina los filtros manage_{$post_type}_posts_columns
y la acción manage_{$post_type}_posts_custom_column
.
EDITADO: Añadido filtro de ordenación de columnas manage_edit-{$post_type}_sortable_columns
y acción pre_get_posts
.
function add_admin_column( $column_title, $post_type, $cb, $order_by = false, $order_by_field_is_meta = false ){
// Cabecera de Columna
add_filter( 'manage_' . $post_type . '_posts_columns', function( $columns ) use ($column_title) {
$columns[ sanitize_title($column_title) ] = $column_title;
return $columns;
} );
// Contenido de Columna
add_action( 'manage_' . $post_type . '_posts_custom_column' , function( $column, $post_id ) use ($column_title, $cb) {
if( sanitize_title($column_title) === $column)
$cb($post_id);
}, 10, 2 );
// ¿Ordenación configurada?
if( !empty( $order_by ) ) {
// Ordenación de Columnas
add_filter( 'manage_edit-' . $post_type . '_sortable_columns', function ( $columns ) use ($column_title, $order_by) {
$columns[ sanitize_title($column_title) ] = $order_by;
return $columns;
} );
// Ordenación de Columnas
add_action( 'pre_get_posts', function ( $query ) use ($order_by, $order_by_field_is_meta) {
if( ! is_admin() || ! $query->is_main_query() )
return;
if ( sanitize_key($order_by) === $query->get( 'orderby') ) {
if($order_by_field_is_meta){
$query->set( 'orderby', 'meta_value' );
$query->set( 'meta_key', sanitize_key($order_by) );
}
else {
$query->set( 'orderby', sanitize_key($order_by) );
}
}
} );
}
}
Uso:
add_admin_column(__('EAN'), 'product', function($post_id){
echo get_post_meta( $post_id , 'ean' , true );
}, 'meta_key_name', true);
El meta_key_name
puede omitirse para evitar la ordenación. De lo contrario, necesitarás conocer el nombre exacto de tu meta_key para que la ordenación funcione correctamente.
add_admin_column(__('Última Modificación'), 'post', function($post_id){
echo get_the_modified_date();
}, 'modified');
En este caso, modified
no es una meta clave.

Funciona perfectamente, gracias. ¿Cómo puedo hacer que la nueva columna creada sea ordenable?

Prueba este artículo en Smashing Magazine https://www.smashingmagazine.com/2017/12/customizing-admin-columns-wordpress/

Esta guía me funcionó. En mi caso, estoy usando CPT UI para crear los tipos de contenido personalizados, ACF para crear los campos personalizados y Code Snippets para unir todo.
He incluido una versión simplificada del código a continuación.
Cambia custom-post-type-slug
, custom_post_type_slug
y custom_column_name
según tus necesidades. Asegúrate de mantener el mismo formato de guiones/guiones bajos al cambiar los nombres.
Ten en cuenta que get_field()
es específico del plugin ACF. Si no estás usando ACF, quizás quieras usar la función incorporada de WordPress get_post_meta()
para recuperar y mostrar los metadatos de las publicaciones.
add_filter('manage_custom-post-type-slug_posts_columns', 'set_custom_edit_custom_post_type_slug_columns');
function set_custom_edit_custom_post_type_slug_columns($columns) {
$columns['custom_column_name'] = 'Título de Columna Personalizada';
return $columns;
}
add_action('manage_custom-post-type-slug_posts_custom_column' , 'custom_custom_post_type_slug_column', 10, 2);
function custom_custom_post_type_slug_column($column, $post_id) {
switch ($column) {
case 'custom_column_name':
echo get_field('custom_column_name', $post_id);
break;
}
}
add_filter('manage_edit-custom-post-type-slug_sortable_columns', 'set_custom_custom_post_type_slug_sortable_columns');
function set_custom_custom_post_type_slug_sortable_columns($columns) {
$columns['custom_column_name'] = 'custom_column_name';
return $columns;
}
add_action('pre_get_posts', 'custom_post_type_slug_custom_orderby');
function custom_post_type_slug_custom_orderby($query) {
if ( ! is_admin()) {
return;
}
$orderby = $query->get('orderby');
if ('custom_column_name' == $orderby) {
$query->set('meta_key', 'custom_column_name');
$query->set('orderby', 'meta_value_num');
}
}

No estoy seguro si son los metadatos personalizados predeterminados que deseas mostrar como columnas, pero podrías considerar usar este plugin gratuito que te permite añadir columnas para mostrar campos personalizados. https://wordpress.org/plugins/codepress-admin-columns/
La versión pro incluso te permite añadir filtrado, ordenación y edición en línea a esas columnas.

¡NO USAR! Dañará tu sitio: PHP Error fatal: No se puede redeclarar AC() (declarada previamente en [redacted]\wp-content\themes\[redacted]\functions.php:628) en [redacted]\wp-content\plugins\codepress-admin-columns\api.php en la línea 9

@PeterKionga-Kamau este es un problema de compatibilidad con tu tema específico. El error que publicaste no aparecerá con un tema predeterminado de WP (como twentytwenty); yo también uso el plugin con el tema Divi y lo encuentro bastante útil

Basado en la respuesta de Carlos (muchas gracias) Quería añadir una pequeña imagen miniatura, pero no una imagen destacada, sino una de un metabox personalizado.
Así que esto es lo que añadí:
add_admin_column(__('Miniatura'), 'obraz', function($post_id){
$image_id = get_post_meta( $post_id , 'custom_thumbnail_metabox' , true );
echo '<img src="'.wp_get_attachment_image_url($image_id).'" />';
Información: El meta del post obtendrá el ID del adjunto/imagen, por eso luego se llama a wp_get_attachment_image_url

Para los pedidos de WooCommerce necesitaba usar el filtro: manage_edit-shop_order_columns.
add_filter( 'manage_edit-shop_order_columns', 'manage_shop_order_posts_columns', 10, 1 );
function manage_shop_order_posts_columns($columns) {
$columns['test'] = 'Prueba';
return $columns;
}
Luego para rellenar el campo:
add_action( 'manage_shop_order_posts_custom_column' , 'manage_shop_order_custom_column', 10, 2 );
function manage_shop_order_custom_column($column, $post_id) {
switch ( $column )
{
case 'test' :
echo '1234';
break;
}
}
