Style WordPress tables?

This is my WordPress table. I created an array so that I could try it out, but I need to add classes and IDs so I can use CSS to style it like the top level plugin page.

How can I add classes to the table elements?

<?php

if(!class_exists('WP_List_Table')){
    require_once( ABSPATH . 'wp-admin/includes/class-wp-list-table.php' );
}


class TT_Example_List_Table extends WP_List_Table {

    var $example_data = array(
            array(
                'ID'        => 1,
                'title'     => '300',
                'rating'    => 'R',
                'director'  => 'Zach Snyder'
            ),
            array(
                'ID'        => 2,
                'title'     => 'Eyes Wide Shut',
                'rating'    => 'R',
                'director'  => 'Stanley Kubrick'
            ),
            array(
                'ID'        => 3,
                'title'     => 'Moulin Rouge!',
                'rating'    => 'PG-13',
                'director'  => 'Baz Luhrman'
            ),
            array(
                'ID'        => 4,
                'title'     => 'Snow White',
                'rating'    => 'G',
                'director'  => 'Walt Disney'
            ),
            array(
                'ID'        => 5,
                'title'     => 'Super 8',
                'rating'    => 'PG-13',
                'director'  => 'JJ Abrams'
            ),
            array(
                'ID'        => 6,
                'title'     => 'The Fountain',
                'rating'    => 'PG-13',
                'director'  => 'Darren Aronofsky'
            ),
            array(
                'ID'        => 7,
                'title'     => 'Watchmen',
                'rating'    => 'R',
                'director'  => 'Zach Snyder'
            )
        );


    function __construct(){
        global $status, $page;

        //Set parent defaults
        parent::__construct( array(
            'singular'  => 'movie',     //singular name of the listed records
            'plural'    => 'movies',    //plural name of the listed records
            'ajax'      => false        //does this table support ajax?
        ) );

    }


    function column_default($item, $column_name){
        switch($column_name){
            case 'rating':
            case 'director':
                return $item[$column_name] . 'hi';
            default:
                return print_r($item,true) . ' hi'; //Show the whole array for troubleshooting purposes
        }
    }


    function column_title($item){

        //Build row actions
        $actions = array(
            'edit'      => sprintf('<a href="?page=%s&action=%s&movie=%s">Edit</a>',$_REQUEST['page'],'edit',$item['ID']),
            'delete'    => sprintf('<a href="?page=%s&action=%s&movie=%s">Delete</a>',$_REQUEST['page'],'delete',$item['ID']),
        );

        //Return the title contents
        return sprintf('%1$s <span style="color:silver">(id:%2$s)</span>%3$s',
            /*$1%s*/ $item['title'],
            /*$2%s*/ $item['ID'],
            /*$3%s*/ $this->row_actions($actions)
        );
    }


    function column_cb($item){
        return sprintf(
            '<input type="checkbox" name="%1$s[]" value="%2$s" />',
            /*$1%s*/ $this->_args['singular'],  //Let's simply repurpose the table's singular label ("movie")
            /*$2%s*/ $item['ID']                //The value of the checkbox should be the record's id
        );
    }


    function get_columns(){
        $columns = array(
            'cb'        => '<input type="checkbox" />', //Render a checkbox instead of text
            'title'     => 'Title',
            'rating'    => 'Rating',
            'director'  => 'Director'
        );
        return $columns;
    }


    function get_sortable_columns() {
        $sortable_columns = array(
            'title'     => array('title',true),     //true means its already sorted
            'rating'    => array('rating',false),
            'director'  => array('director',false)
        );
        return $sortable_columns;
    }


    function get_bulk_actions() {
        $actions = array(
            'delete'    => 'Delete'
        );
        return $actions;
    }


    function process_bulk_action() {

        //Detect when a bulk action is being triggered...
        if( 'delete'===$this->current_action() ) {
            wp_die('Items deleted (or they would be if we had items to delete)!');
        }

    }


    function prepare_items() {


        $per_page = 5;


        $columns = $this->get_columns();
        $hidden = array();
        $sortable = $this->get_sortable_columns();


        $this->_column_headers = array($columns, $hidden, $sortable);


        $this->process_bulk_action();


        $data = $this->example_data;


        function usort_reorder($a,$b){
            $orderby = (!empty($_REQUEST['orderby'])) ? $_REQUEST['orderby'] : 'title'; //If no sort, default to title
            $order = (!empty($_REQUEST['order'])) ? $_REQUEST['order'] : 'asc'; //If no order, default to asc
            $result = strcmp($a[$orderby], $b[$orderby]); //Determine sort order
            return ($order==='asc') ? $result : -$result; //Send final sort direction to usort
        }
        usort($data, 'usort_reorder');



        $current_page = $this->get_pagenum();


        $total_items = count($data);



        $data = array_slice($data,(($current_page-1)*$per_page),$per_page);



        $this->items = $data;


        $this->set_pagination_args( array(
            'total_items' => $total_items,                  //WE have to calculate the total number of items
            'per_page'    => $per_page,                     //WE have to determine how many items to show on a page
            'total_pages' => ceil($total_items/$per_page)   //WE have to calculate the total number of pages
        ) );
    }

}



function tt_add_menu_items(){
    add_menu_page('Example Plugin List Table', 'List Table Example', 'activate_plugins', 'tt_list_test', 'tt_render_list_page');
} add_action('admin_menu', 'tt_add_menu_items');


function tt_render_list_page(){

    $testListTable = new TT_Example_List_Table();
    $testListTable->prepare_items();

    ?>
    <div class="wrap">

        <div id="icon-users" class="icon32"><br/></div>
        <h2>List Table Test</h2>


        <form id="movies-filter" method="get">
            <input type="hidden" name="page" value="<?php echo $_REQUEST['page'] ?>" />
            <?php $testListTable->display() ?>
        </form>

    </div>
    <?php
}

Related posts

Leave a Reply

1 comment

  1. The only way to do this is by overriding some of the methods of the WP_List_Table class.

    I went ahead and modified your class to support conditional HTML classes for each tr/td in the table. You weren’t clear enough about to which elements you want classes applied, nor how exactly you want to specify that, so excuse me if it’s not what you wanted(and please specify further details).

    You can see the full code(only the TT_Example_List_Table class is there – the rest is the same) here.

    Basically you define a class property called $cond_classes. This property is a multidimensional array of conditions. In there you have two top-level keys which are reserved – “odd” and “even”. As you can guess they will be accessed for each row that is either odd or even.
    The rest of the top-level keys can be column id’s or item ID’s.

    Each top-level key can hold either an array or a string
    If the top-level key holds a string, then when this condition is met, that class is added
    If the top-level key holds an array, then it’s looped through.
    The second-level array can have string values and key=>value pairs, where the key is the class and the value
    is an array of conditions.

    I guess that’s quite confusing, but the example bellow should give you an idea of how this works.

    var $cond_classes = array(
        'odd' => array(
            'odd-class', // This class will always be given to odd rows and their columns
            'special-odd-class' => array( // This class will only be given to odd rows and their columns if the rows is for an item with ID 1, 4 or 7
                'ID' => array( 1, 4, 7 )
            )
        ),
        'even' => array(
            'even-class'
        ),
        'title' => array(
            'custom_title_class',
            'special_title_class' => array(
                'ID' => array( 3, 7 ), // This will only be given to the "title" column for an item with ID 3 or 7
                'title' => 'The Fountain', // This will only be given to the "title" column for an item with title "The Fountain"
            ),
        ),
        7 => 'id_7_class', // This will be given to a row and it's columns for item with ID 7
    );

    And you can see the applied classes in the resulting table:
    HTML code preview

    Hope that helps! If you have any questions – go ahead 🙂