1. Home
  2. Knowledge Base
  3. WooCommerce Product Table
  4. Developer Documentation

Adding a custom column to the product table

This article explains how to add a custom column in WooCommerce Product Table. Custom columns are a good way to display extra data which is not available in the standard table columns. This article is aimed at developers.


Do you need a custom column?

First, decide whether you need a custom column. If your column will fetch custom data from the database, display product information dynamically, or create complex HTML, then a custom column is the way to go.

However, if you simply need some extra data for each product, consider whether a custom field would meet your needs. You could create a custom field using a suitable plugin (ACF, Pods, etc) then add the data to each product. To display the column in your table, add a custom field column in the usual way.

Method 1

The first method uses the wc_product_table_custom_column_<column> hook. This is the simplest way to add a custom column.

  1. Add a custom column to the your table. This can added to the settings page or directly in the shortcode using the columns option. The column name can be anything you like: sale_price, wholesale_discount, file_type, product_region, etc, it doesn't matter. As long as the column name is not an existing column in the product table plugin.
  2. Next, add the wc_product_table_custom_column_<column> hook. Place the code in a custom plugin or your theme's functions.php file. The return value of the hook is the data that will be added to the table. The dynamic portion of the hook - <column> - is the name you gave to the column in step 1. So if your column name is product_region, then the hook is: wc_product_table_custom_column_product_region. The hook takes 3 arguments - the data to return (an empty string is always passed to the hook), the current WC_Product object, and the table arguments used to create the table which is an instance of Barn2\Plugin\WC_Product_Table\Table_Args.
add_filter( 'wc_product_table_custom_column_product_region', function( $data, WC_Product $product, $args ) { 
    $data = 'Something'; // create your data here
    return $data;
}, 10, 3 );

Example shortcode including the custom column:

[product_table columns="name,description,product_region,price,buy"]
We've partnered with Codeable to provide our customers with expert help if required.

Method 2

Method 2 is slightly more complex, but is useful if you want more control over the sorting or filtering of the column. For example, if your column is sorted in a non-standard way (not alphabetically), then use this method and provide an implementation for the get_sort_data method.

  1. Add the column in the same way as Method 1. Your column can be any name you like.
  2. Next, add the wc_product_table_custom_table_data_<column> hook. Place the code in a custom plugin or your theme's functions.php file. This hook should return a class which implements the Table_Data_Interface. The dynamic portion of the hook - <column> - is the name you gave to the column in step 1. The class will retrieve the data for your custom column. We recommend extending the Abstract_Product_Data class as this provides stubs for all methods on the interface. Consult the PHP documentation for more details.
  3. Complete the code for your custom class. As a minimum you should implement the get_data method to return the data for the custom column. Optionally, you can also provide a get_sort_data or get_filter_data method if your column requires it (more on that below). The example below uses an anonymous class but you could use a standard class and return an instance of that.
use Barn2\Plugin\WC_Product_Table\Data\Abstract_Product_Data;
use Barn2\WPT_Lib\Table\Table_Data_Interface;
use WC_Product;

add_action( 'init', function () {
    if ( ! interface_exists( 'Table_Data_Interface' ) ) {
        return;
    }

    add_filter( 'wc_product_table_custom_table_data_product_region', [ 'wpt_get_product_region' ], 10, 3 );
} );

function wpt_get_product_region( $data, WC_Product $product, $args ) {
    
    return new class( $product ) extends Abstract_Product_Data implements Table_Data_Interface {

	public function get_data() {
	    $data = 'Something'; // create your data here
            return $data;
	}

    };
}

Sorting and filtering

Using Method 2, you have the option to provide the get_sort_data or get_filter_data methods. These are used by the plugin to sort and filter (search) the data in your column.

Sorting

The plugin will attempt to sort your data automatically. For example, if your column contains textual data it will sort alphabetically, if it contains numbers it will sort numerically. If you find the sorting doesn't work as you expect, implement the get_sort_data method and return values that will sort from low to high or high to low.

In this example, the custom column returns the product's publish date (this is the same as the date column provided by the plugin). To sort this correctly, you should implement the get_sort_data and return a sortable version of the date, rather than the text representation.

public function get_data() {
    return get_the_date( 'd M Y, $this->get_product_id() );
}

public function get_sort_data() {
    return get_the_date( 'U', $this->get_product_id() );
}

Filtering

The plugin will use the data displayed in the table for searching. If you want to provide different searchable data which is applied when a user types in the search box, use the get_filter_data method.

In this example, the custom column displays a customer's first name. Providing a get_filter_data method allows users to search the table by the customer's first or last name:

public function get_data() {
    return $customer->first_name;
}

public function get_filter_data() {
    return $customer->first_name . ' ' . $customer->last_name;
}

Setting the column heading

The product table will give your column a heading based on its name. So in the above example the heading would be "Product Region". If you want a different column heading, you can set this in the usual way by adding a : (colon) after the column followed by the heading:

[product_table columns="name,description,product_region:Region,price,buy"]

Related Articles

If searching the knowledge base hasn't answered your question, please contact support.