Create a Simple CRM in WordPress: Adding Columns to WP_List_Table


This Cyber Monday Envato Tuts+ courses will be reduced to just $3. Don't miss out.

This post is part of a series called Create a Simple CRM in WordPress.
Create a Simple CRM in WordPress: Advanced Custom Fields
Create a Simple CRM in WordPress: Extending WordPress Search to Include Custom Fields

We’ve been looking at how to create a simple CRM system in WordPress. In the last part of this series, we used Advanced Custom Fields to add custom fields to our Contacts custom post type. We learned how to use Advanced Custom Fields and configure it to work programmatically.

Today, we’ll cover how to display the data stored in our custom fields right within our contacts table.

All About WP_List_Table

Each post type that has a dashboard uses the WP_List_Table class to render the familiar table and its associated actions:

By default, WordPress will display the following columns:

  • checkbox (used to select/deselect posts, which can then have actions applied to them)
  • title
  • author
  • comments
  • date

For our Contact custom post type, this isn’t very useful if we want to quickly see key details at a glance, such as the contact’s phone number or photo.

WordPress provides a filter and an action that can be used to add new columns to the WP_List_Table and determine its output for each post.

Let’s start by adding the manage_edit-{POST_TYPE}_columns filter to our plugin class’ construct. {POST_TYPE} will be the name of our Post Type, which in this case is contact:

We also need to define our add_table_columns() function, which tells WordPress the names of our additional columns that we’d like to display on our Contacts table. This function accepts an array of existing columns, which we can extend by adding our custom table columns.

We make sure that the array keys match ACF’s custom field names. If you have different fields, be sure that your column key names match your fields’ field name setting.

View your Contacts table by clicking on Contacts in the WordPress dashboard menu, and you’ll see our new columns:

However, there’s no data being displayed for each Contact in the table. We need to add the manage_{POST_TYPE}_posts_custom_column action to our plugin class’ constructor. {POST_TYPE} will again be the name of our post Type, which in this case is contact:

We also need to define our output_table_columns_data() function, which tells WordPress what to display for each Contact and column combination. Because we made sure our column key names match our ACF Field Names, this makes our coding easier. Advanced Custom Fields has a get_field() function, which accepts both Field Name and Post ID parameters to retrieve the value stored:

Reload your Contacts table, and you’ll see your custom fields:

Depending on your PHP configuration, the Photo column will either be blank, or output a PHP notice:

The image field in Advanced Custom Fields returns an array when using get_field(), comprising of the image details and each registered image size’s URL, width and height (a registered image size is typically based on your installed Themes and Plugins).

Let’s modify our function to output the right array data to display an image:

Reload your Contacts Table, and you should see each Contact’s photo:

Sortable Columns

What if we need to quickly sort our Contacts by name, phone number or email address? We can already sort on the name (or, rather, the title) column, but right now there’s no functionality to tell WordPress how to sort on our phone number and email address columns.

Back to our plugin’s constructor. We need to add the manage_{POST_TYPE}_posts_custom_column filter to our plugin class’ construct, to tell WordPress that we want to enable certain columns to be sortable. {POST_TYPE} will again be the name of our Post Type, which in this case is contact:

As with our previous actions and filters, we also need to define our define_sortable_table_columns() function, which tells WordPress which columns can be sortable:

Hover the mouse cursor over the Email Address and Phone Number columns, and you’ll see an arrow appear, showing us that we can sort by the data in the relevant column:

Right now, clicking on the column header to sort by its data won’t do anything, as the orderby parameter that’s set in the URL isn’t one that WordPress will recognize.

In our plugin’s constructor, let’s add a filter on the request method, and then define our function to check if we’re trying to sort by a custom column (and if so, amend the posts query so WordPress can understand it):

Because the request filter runs on every page load of WordPress (whether the frontend web site or WordPress dashboard interface), we want to minimize how often it’s called. We do this by only adding the filter if we are in the WordPress Administration (is_admin()).

Next, let’s define our orderby_sortable_table_columns() function:

This function checks that we are viewing our Contacts Custom Post Type, and if so that an orderby parameter has been set matching either email_address or phone_number. These are set if the user has clicked a column in the Contacts Table to order by Phone Number or Email Address.

Let’s click on the Email Address column, and we’ll see the results are ordered correctly:

Clicking it again will reverse the order of results:

Up Next…

In the next article, we’re going to extend the filter and search functionality, allowing us to search the data stored within our Advanced Custom Fields.