Implementing Lesson 28 — Adding Sortable Columns to the Auctions Table (Step by Step)


Difficulty: Intermediate
Project: Flipnzee Auctions Plugin
Lesson Implemented: Lesson 28


Introduction

In the previous lessons, we transformed our custom Auctions page into a professional WordPress administration screen by adding pagination and search functionality.

Although administrators could now search for auctions, they still could not sort the table by different columns. WordPress users expect to be able to click column headings like ID, Start Price, or Created At to sort data.

In this implementation, we enhanced our custom WP_List_Table by making its columns sortable.


Step 1 — Define the Sortable Columns

The first step was to tell WordPress which columns should be sortable.

Inside:

admin/class-auctions-table.php

we added a new method:

public function get_sortable_columns() {

	return array(
		'id'            => array( 'id', true ),
		'listing_id'    => array( 'listing_id', false ),
		'start_price'   => array( 'start_price', false ),
		'reserve_price' => array( 'reserve_price', false ),
		'buy_now_price' => array( 'buy_now_price', false ),
		'status'        => array( 'status', false ),
		'created_at'    => array( 'created_at', false ),
	);
}

Each array entry tells WordPress which database column should be used for sorting.


Step 2 — Enable Sorting in prepare_items()

Defining sortable columns alone is not enough.

Inside prepare_items(), we updated the column headers:

From:

$this->_column_headers = array(
	$this->get_columns(),
	array(),
	array(),
);

To:

$this->_column_headers = array(
	$this->get_columns(),
	array(),
	$this->get_sortable_columns(),
);

This small change tells WP_List_Table to convert the column headings into clickable links.


Step 3 — Read Sorting Parameters

Next, we needed to determine which column the administrator clicked.

Inside prepare_items(), we added:

$orderby = isset( $_GET['orderby'] )
	? sanitize_key(
		wp_unslash( $_GET['orderby'] )
	)
	: 'created_at';

$order = isset( $_GET['order'] )
	? strtoupper(
		sanitize_text_field(
			wp_unslash( $_GET['order'] )
		)
	)
	: 'DESC';

Why?

When a user clicks a sortable column, WordPress automatically appends parameters such as:

orderby=start_price
order=ASC

We safely read these values before using them.


Step 4 — Pass Sorting Information to the Database Layer

Previously, our manager class received only:

  • page size
  • offset
  • search term

We extended the call to include:

Flipnzee_Auction_Manager::get_all_auctions(
	$per_page,
	$offset,
	$search,
	$orderby,
	$order
);

Now the database query knows exactly how to sort the results.


Step 5 — Update the Manager Method

Inside:

includes/class-auction-manager.php

we modified the method signature:

public static function get_all_auctions(
	$per_page = 20,
	$offset = 0,
	$search = '',
	$orderby = 'created_at',
	$order = 'DESC'
)

This allows sorting preferences to be passed from the table class.


Step 6 — Validate the Column Name

Unlike values, SQL column names cannot be protected using prepared statements.

Instead, we created a whitelist:

$allowed_columns = array(
	'id',
	'listing_id',
	'start_price',
	'reserve_price',
	'buy_now_price',
	'status',
	'created_at',
);

We then verified the requested column:

if ( ! in_array( $orderby, $allowed_columns, true ) ) {
	$orderby = 'created_at';
}

This prevents invalid or malicious column names from being used.


Step 7 — Validate the Sort Direction

We also limited the sort direction:

$order = ( 'ASC' === strtoupper( $order ) )
	? 'ASC'
	: 'DESC';

Only two values are accepted:

  • ASC
  • DESC

Anything else automatically falls back to descending order.


Step 8 — Update the SQL Query

Previously, every query ended with:

ORDER BY created_at DESC

We replaced it with:

ORDER BY {$orderby} {$order}

Both the search query and the default query were updated so that sorting works in every situation.


Step 9 — Test the Feature

After uploading the updated plugin, we verified that:

  • ID became clickable
  • Listing ID became clickable
  • Start Price became clickable
  • Reserve Price became clickable
  • Buy Now Price became clickable
  • Status became clickable
  • Created At became clickable

Clicking a column heading automatically updated the URL and changed the sort order.


Challenges Encountered

This lesson involved several small debugging tasks before everything worked correctly.

Some of the issues included:

  • Accidentally duplicating the search query inside get_all_auctions().
  • Forgetting to replace ORDER BY created_at DESC with the dynamic sorting variables.
  • Leaving the third element of _column_headers empty, which prevented WordPress from displaying clickable column headings.

By resolving these issues one by one, the sortable table behaved exactly as expected.


What We Learned

This implementation introduced several important WordPress concepts:

  • Using get_sortable_columns()
  • Registering sortable columns with WP_List_Table
  • Reading URL parameters safely
  • Passing sorting information between classes
  • Validating SQL identifiers using a whitelist
  • Restricting sort directions
  • Building flexible SQL queries while maintaining security

These are common techniques used in professional WordPress plugins that display tabular data.


Final Result

After completing this implementation, the Flipnzee Auctions plugin now provides a much more user-friendly administration interface.

Administrators can click any supported column heading to reorder the table, making it easier to analyse auction data and locate important records.

Combined with the search and pagination features implemented in earlier lessons, the Auctions page now closely resembles the polished interfaces found throughout the WordPress admin dashboard.


Download Source Code

Download the starting version of the plugin before implementing sortable columns:

⬇ Download Plugin (After Lesson 27) (3 downloads )

Download the completed version containing fully functional sortable columns:

⬇ Download Plugin (After Lesson 28) (0 downloads )

Leave a Reply