How to Add Columns to WordPress List Tables
Christopher Davis has written this article. More details coming soon.
At the heart of all the various nicely-formatted list tables in the WordPress admin area is a PHP class called WP_List_Table. Reading the source of WP_List_Table and its various children can be enlightening and may reveal the secrets of the universe – well, probably not the secrets thing.
This tutorial will show you how to add a custom column to the page list table. You can apply these methods to any list table in the core WordPress admin pages.
Our task: add a column to the page list table that will display the page’s template.
The first step is to hook into load-edit.php, which will fire whenever any post list table is load – this includes custom post types and pages. We’ll use get_current_screen to grab the screen object and make sure we’re on the page list table.
<?php
add_action('load-edit.php', 'pmg_ltt_load');
function pmg_ltt_load()
{
$screen = get_current_screen();
if (!isset($screen->post_type) || 'page' != $screen->post_type) {
return;
}
}
If you wanted to add columns to ALL posts list tables, you could use this code, but remove the if statement above.
An examination of the main list table class reveals a filter named manage_{$screen->id}_columns. $screen is the WP_Screen object returned by get_current_screen.
We’ll hook into the manage_{$screen->id}_columns and add another column to our table. The $cols argument passed into the callback function is an associative array of key => label pairs.
<?php
add_action('load-edit.php', 'pmg_ltt_load'); function pmg_ltt_load() { $screen = get_current_screen(); if (!isset($screen->post_type) || 'page' != $screen->post_type) { return; } add_filter("manage_{$screen->id}_columns", 'pmg_ltt_add_columns'); } function pmg_ltt_add_columns($cols) { $cols['template'] = __('Page Template', 'pmg-list-table'); return $cols; }
The end result is a new, empty column on the page list table.
To display content, we hook into manage_{$screen->post_type}_posts_custom_column. We’ll modify our load function a bit:
<?php
add_action('load-edit.php', 'pmg_ltt_load');
function pmg_ltt_load()
{
$screen = get_current_screen();
if (!isset($screen->post_type) || 'page' != $screen->post_type) {
return;
}
add_filter("manage_{$screen->id}_columns", 'pmg_ltt_add_columns');
add_action(
"manage_{$screen->post_type}_posts_custom_column",
'pmg_ltt_column_cb',
10, 2
);
}
the important thing to note is that the function hooked into manage_{$screen->post_type}_posts_custom_column will fire on every custom column. Not just your own. So we need to check that. List tables with lots of custom columns may want to use a switch statement, but we’ll just use a simple if.
<?php
function pmg_ltt_column_cb($col, $post_id)
{
static $templates;
if ('template' == $col) {
if (empty($templates)) {
$templates = array_flip(get_page_templates());
}
$tmp = get_post_meta($post_id, '_wp_page_template', true);
if ($tmp && isset($templates[$tmp])) {
echo esc_html($templates[$tmp])
} else {
esc_html_e('Default Template', 'pmg-list-table');
}
}
Enabling a column for sorting is easy: simply hook into manage_{$screen->id}_sortable_columns. First modify our load function:
add_action('load-edit.php', 'pmg_ltt_load');
function pmg_ltt_load()
{
$screen = get_current_screen();
if (!isset($screen->post_type) || 'page' != $screen->post_type) {
return;
}
// snip snip
add_filter("manage_{$screen->id}_sortable_columns", 'pmg_ltt_add_sortable');
// snip snip
}
And the callback function simply adds a new key that matches the key of our column we added earlier. The array value is going to be the param we want in the URL as the ‘orderby’ key.
function pmg_ltt_add_sortable($cols)
{
$cols['template'] = 'template';
return $cols;
}
While the above makes the template column nice and clickable, it doesn’t actually sort things for you. We have to do that our selves. Yet another modification to the load function to hook into request
add_action('load-edit.php', 'pmg_ltt_load');
function pmg_ltt_load() { $screen = get_current_screen(); if (!isset($screen->post_type) || 'page' != $screen->post_type) { return; } // snip snip add_filter('request', 'pmg_ltt_do_sort'); }
The function hooked into request checks to see if orderby is set and if it’s “template”. If it is, we’ll alter the query to order by meta_value and set an appropriate meta_key.
Stay in touch
Subscribe to our newsletter
By clicking and subscribing, you agree to our Terms of Service and Privacy Policy
That it! The above techniques can be used on nearly every list table in the WordPress admin.