Adding Columns To WordPress Screen Options

Adding the Screen Options drop down to a custom WordPress admin page takes some trickery which was described in the prior Screen Options blog post.  Using the “magic sauce” of the per_page option and adding it to the class that renders your admin page and handles page interaction is an easy way to get that started.    Assuming you already have the Screen Options rendering with something on there, probably Pagination settings, you can now add a column selector.   This is especially useful for admin pages built on top of the WordPress WP_List_Table (for private use only but everyone-and-their-brother is using it).

Getting The List Of Columns

The easiest way to get the list of columns to appear is to add a manage_{$screen-id}_columns filter to your app.   In the Store Locator Plus location manager I am setting this up in the class constructor as the WP_Screen interface likes to know about the columns very early in the process; well before the page rendering happens.

First we need to get our current screen.  This makes it easy to ensure your screen->id needed for the filter is an exact match for what the filter trigger will be looking for.  This is managed in the get_wp_screen() method in my example.

We then need to tell WordPress to run our manage_{$screen-id}_columns code, which is the private manage_columns() method in this example.   It accepts a list of already-in-play column slugs and titles, usually empty, and should send back a named array with the key set to the slug and the value set to the title.

Since our class is a WP_List_Table derivative and we already wired up the screen, the screen_options() WordPress function will now see our list of column names as stored in the static variable managed in the WordPress Core screen.php function get_column_headers.

The Code

<?php
defined( 'ABSPATH'     ) || exit;
if ( ! class_exists( 'SLP_Admin_Locations' ) ) {
    require_once( ABSPATH . 'wp-admin/includes/class-wp-list-table.php' );

    class SLP_Admin_Locations extends WP_List_Table {
        private $wp_screen;

        /**
         * Called when this object is created.
         */
        function __construct( $args = array() ) {
            $screen = $this->get_wp_screen();
            add_filter( 'manage_' . $screen->id . '_columns' , array( $this , 'manage_columns') );
        }

       /**
        * Set the columns we will render on the manage locations page.
        */
       public function get_columns() {
          $this->columns = array(
             'sl_id'               => __( 'Actions', 'store-locator-le' ),
             'sl_store'            => __( 'Name', 'store-locator-le' ),
             'sl_address'          => __( 'Address', 'store-locator-le' ),
             'sl_address2'         => __( 'Address 2', 'store-locator-le' ),
             'sl_city'             => __( 'City', 'store-locator-le' ),
             'sl_state'            => __( 'State', 'store-locator-le' ),
             'sl_zip'              => __( 'Zip', 'store-locator-le' ),
             'sl_country'          => __( 'Country', 'store-locator-le' ),
             'sl_initial_distance' => __( 'Distance', 'store-locator-le' ),
             'sl_description'      => __( 'Description', 'store-locator-le' ),
             'sl_email'            => $this->slplus->WPML->get_text( 'label_email' ),
             'sl_url'              => $this->slplus->WPML->get_text( 'label_website' ),
             'sl_hours'            => $this->slplus->WPML->get_text( 'label_hours' ),
             'sl_phone'            => $this->slplus->WPML->get_text( 'label_phone' ),
             'sl_fax'              => $this->slplus->WPML->get_text( 'label_fax' ),
             'sl_image'            => $this->slplus->WPML->get_text( 'label_image' ),
          );

          return $this->columns;
       }

       /**
        * Get a list of all, hidden and sortable columns, with filter applied
        *
        * @return array
        */
       public function get_column_info() {
          if ( ! isset( $this->_column_headers ) ) {
             $this->_column_headers = array(
                $this->get_columns(),
                array(),
                array(),
                'sl_id',
             );
          }

          return $this->_column_headers;
       }

       /**
        * Get the wp_screen property.
        */
       private function get_wp_screen() {
          if ( empty( $this->wp_screen ) ) {
             $this->wp_screen = get_current_screen();
          }
          return $this->wp_screen;
       }

       /**
        * Set up our screen columns.
        *
        * Impacts screen options column list.
        *
        * @param   array   columns     the existing columns
        * @return  array               key = field slug, value = title
        */
       public function manage_columns( $columns ) {
          $this->get_column_info();
          return $this->_column_headers[0];
       }
    }
}

The User Experience

If everything is wired up properly you should see the screen options drop down with a new Columns header and list of check boxes that  let the user choose which columns to show on the interface.   Here is an example from the Manage Locations interface of Store Locator Plus when we have the Experience and Power add ons active.

Column Selector 2017-06-16_10-50-08.png

Leave a Reply