I wrote a function that combines manage_{$post_type}_posts_columns
filter and manage_{$post_type}_posts_custom_column
action.
EDIT: Added column sorting filter manage_edit-{$post_type}_sortable_columns
and pre_get_posts
action.
function add_admin_column( $column_title, $post_type, $cb, $order_by = false, $order_by_field_is_meta = false ){
// Column Header
add_filter( 'manage_' . $post_type . '_posts_columns', function( $columns ) use ($column_title) {
$columns[ sanitize_title($column_title) ] = $column_title;
return $columns;
} );
// Column Content
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 );
// OrderBy Set?
if( !empty( $order_by ) ) {
// Column Sorting
add_filter( 'manage_edit-' . $post_type . '_sortable_columns', function ( $columns ) use ($column_title, $order_by) {
$columns[ sanitize_title($column_title) ] = $order_by;
return $columns;
} );
// Column Ordering
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) );
}
}
} );
}
}
Usage:
add_admin_column(__('EAN'), 'product', function($post_id){
echo get_post_meta( $post_id , 'ean' , true );
}, 'meta_key_name', true);
The meta_key_name
can be omitted to avoid sorting. Otherwise, you will need to know your exact meta_key name for sorting to work properly.
add_admin_column(__('Last Modified'), 'post', function($post_id){
echo get_the_modified_date();
}, 'modified');
In this case, modified
isn't a meta key.