Add Custom Columns and Filterable Dropdowns to WordPress Admin Post Lists
Add an ISBN column and a taxonomy dropdown filter to a WordPress custom post type in the admin list table.
Admin list tables become much more useful when editors can see important metadata without opening every post. This example adds an ISBN column to a book custom post type and adds a filterable Book genre dropdown backed by the book_genre taxonomy.
Change the post type, taxonomy, and meta key to match the content model on your site. Add the snippet to a plugin or child theme’s functions.php file.
Add a custom column
add_filter( 'manage_book_posts_columns', function( $columns ) { $columns['book_isbn'] = __( 'ISBN', 'my-site' ); return $columns;} );
add_action( 'manage_book_posts_custom_column', function( $column, $post_id ) { if ( 'book_isbn' === $column ) { echo esc_html( get_post_meta( $post_id, '_book_isbn', true ) ?: '—' ); }}, 10, 2 );The manage_{post_type}_posts_columns filter defines the table headings, while manage_{post_type}_posts_custom_column renders the cell for each row. The value is escaped at output time because post meta should not be trusted as HTML.
Add a taxonomy dropdown filter
add_action( 'restrict_manage_posts', function() { $screen = get_current_screen();
if ( ! $screen || 'edit-book' !== $screen->id ) { return; }
wp_dropdown_categories( array( 'show_option_all' => __( 'All book genres', 'my-site' ), 'taxonomy' => 'book_genre', 'name' => 'book_genre', 'orderby' => 'name', 'order' => 'ASC', 'hide_empty' => false, 'show_count' => true, 'hierarchical' => true, 'option_none_value' => '', 'selected' => isset( $_GET['book_genre'] ) ? absint( $_GET['book_genre'] ) : 0, ) );} );
add_action( 'pre_get_posts', function( $query ) { if ( ! is_admin() || ! $query->is_main_query() || 'book' !== $query->get( 'post_type' ) ) { return; }
$term_id = isset( $_GET['book_genre'] ) ? absint( $_GET['book_genre'] ) : 0;
if ( $term_id ) { $query->set( 'tax_query', array( array( 'taxonomy' => 'book_genre', 'field' => 'term_id', 'terms' => $term_id, ), ) ); }} );restrict_manage_posts places the control above the list table. pre_get_posts applies the selected term to the main admin query, so pagination and result counts remain correct.
Keep filters scoped
Always check the current screen or post type. An unscoped callback can add a genre dropdown to unrelated admin screens or change front-end queries. WordPress’s references for custom post list columns and restrict_manage_posts cover the underlying extension points.
For another admin workflow, see how to disable Gutenberg for selected post types or roles.