This website uses cookies to ensure you get the best possible experience. See our Cookies Policy.

PMG Digital Made for Humans

How to Add Columns to WordPress List Tables

4 MINUTE READ | September 14, 2012

How to Add Columns to WordPress List Tables

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.

<?phpadd_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

Bringing news to you

Subscribe to our newsletter

That it! The above techniques can be used on nearly every list table in the WordPress admin.


Posted by Christopher Davis

Related Content

thumbnail image

Get Informed

PMG Innovation Challenge Inspires New Alli Technology Solutions

4 MINUTES READ | November 2, 2021

Get Informed

Applying Function Options to Domain Entities in Go

11 MINUTES READ | October 21, 2019

thumbnail image

Get Informed

My Experience Teaching Through Jupyter Notebooks

4 MINUTES READ | September 21, 2019

Get Informed

Trading Symfony’s Form Component for Data Transfer Objects

8 MINUTES READ | September 3, 2019

Get Inspired

Working with an Automation Mindset

5 MINUTES READ | August 22, 2019

Get Informed

Parsing Redshift Logs to Understand Data Usage

7 MINUTES READ | May 6, 2019

Get Inspired

3 Tips for Showing Value in the Tech You Build

5 MINUTES READ | April 24, 2019

thumbnail image

Get Informed

Testing React

13 MINUTES READ | March 12, 2019

Get Inspired

Tips for Designing & Testing Software Without a UX Specialist

4 MINUTES READ | March 6, 2019

Get Informed

A Beginner’s Experience with Terraform

4 MINUTES READ | December 20, 2018

ALL POSTS