The WordPress posts list table shows title, author, categories, tags, comments, and date by default. For content-heavy sites this is often not enough context to manage posts efficiently, editors need to see at a glance whether a post has a featured image, what its reading time is, or what a key custom field contains. Adding custom columns to the list table puts that information front and center without requiring anyone to open each post individually.
The Code
This snippet adds a featured image thumbnail column that appears just before the title column. Add it to your functions.php or a site-specific plugin. The three hooks work together: one registers the column, one renders its content, and one injects a small CSS rule to keep the column width narrow.
The manage_posts_columns Filter
The manage_posts_columns filter receives the current column array and expects a modified array in return. The snippet uses a loop to rebuild the array, inserting the new thumbnail column immediately before the title key. This positioning approach is more reliable than using array_splice() and works even if the default column order changes in a future WordPress version.
For custom post types, replace manage_posts_columns with manage_{post_type}_posts_columns where {post_type} is your post type slug. For example: manage_nahnu_snippet_posts_columns.
The manage_posts_custom_column Action
This action fires for each custom column on each row. The callback receives the column key and the current post ID. The snippet checks for the thumbnail key and renders the featured image at 60×60 pixels using get_the_post_thumbnail(). When no thumbnail exists, a neutral placeholder div is shown so the column height remains consistent across all rows.
Adding a Custom Field Column
To add a custom field value as a column, add another key to the column filter array and handle it in the action callback using get_post_meta( $post_id, '_your_meta_key', true ). Custom field columns make the most sense for post types where that field is essential context, for example a reading time estimate on blog posts, or a client name on project post types.
Making Columns Sortable
Text-based custom field columns can be made sortable by hooking into manage_edit-post_sortable_columns to register the column as sortable, and then using the pre_get_posts filter to modify the query when that column is selected for sorting. Image columns like the thumbnail example aren’t meaningful to sort and are best left as non-sortable.
Page and Custom Post Type Variants
The hooks in this snippet apply to the standard post post type. For pages use manage_pages_columns and manage_pages_custom_column. For custom post types use the manage_{post_type}_posts_columns and manage_{post_type}_posts_custom_column variants.
// Add the columns
add_filter( 'manage_posts_columns', function( $columns ) {
$new = [];
foreach ( $columns as $key => $label ) {
if ( $key === 'title' ) {
$new['thumbnail'] = 'Image';
}
$new[ $key ] = $label;
}
return $new;
} );
// Render the column content
add_action( 'manage_posts_custom_column', function( $column, $post_id ) {
if ( $column === 'thumbnail' ) {
$thumb = get_the_post_thumbnail( $post_id, [ 60, 60 ] );
if ( $thumb ) {
echo '<div style="width:60px;height:60px;overflow:hidden;border-radius:4px">' . $thumb . '</div>';
} else {
echo '<div style="width:60px;height:60px;background:#f1f5f9;border-radius:4px"></div>';
}
}
}, 10, 2 );
// Make the thumbnail column narrow
add_action( 'admin_head', function() {
$screen = get_current_screen();
if ( $screen && $screen->id === 'edit-post' ) {
echo '<style>.column-thumbnail { width: 80px; }</style>';
}
} );
