WordPress: Sortable Custom Columns

| 2 comments

This entry is part of my WordPress development series, providing tutorials on specific things you can do in WordPress. Read some more?

Continuing on from the previous tutorial where we added custom columns, we are now going to make these columns sortable like the regular default columns in WordPress (such as post/page title and publish date).

For simplicity, we will continue to work in our functions.php file. You can edit this file by going to Appearance > Editor in your WordPress admin panel, or using a text editor with FTP.

From the last tutorial, I have already created my custom columns for my custom post type “Cats”. So first we have to tell WordPress to make our columns sortable using the function add_filter().

// Make columns sortable
add_filter( 'manage_edit-cf_cats_sortable_columns', 'cats_sortable_cols' );

function cats_sortable_cols( $columns ) {

	$columns['age'] = 'age';
	$columns['toy'] = 'toy';

	return $columns;
}

The first parameter is the name of the filter our second parameter is hooked to. It’s in the format manage_edit-${post_type}_sortable_columns. You can see I have replaced ${post_type} with the name of my custom post type, cf_cats. The second parameter is the name of the function we are calling in line 4, which returns the names of our columns (which are the same from when we created them in the previous tutorial).

Now we only want to run our customization when we are on the edit.php page in the Admin area, so we use the add_action() function.

// Only run our customization on the 'edit.php' page in the admin
add_action( 'load-edit.php', 'edit_cat_load' );

function edit_cat_load() {
	add_filter( 'request', 'sort_cat_columns' );
}

When the edit.php page is loaded (first parameter), our function (second parameter) is called which is on line 4, and it calls our next function:

// Sort the posts by custom columns
function sort_cat_columns( $vars ) {

	// Check if we're viewing the 'cf_cats' custom post type
	if ( isset( $vars['post_type'] ) && 'cf_cats' == $vars['post_type'] ) {

		// Check if 'orderby' is set to 'age'
		if ( isset( $vars['orderby'] ) && 'age' == $vars['orderby'] ) {

			// Merge the query vars with our custom variables
			$vars = array_merge(
				$vars,
				array(
					'meta_key' => '_cf_cat_age',
					'orderby' => 'meta_value_num'
				)
			);
		}

		// Check if 'orderby' is set to 'toy'
		if ( isset( $vars['orderby'] ) && 'toy' == $vars['orderby'] ) {

			// Merge the query vars with our custom variables
			$vars = array_merge(
				$vars,
				array(
					'meta_key' => '_cf_cat_toy',
					'orderby' => 'meta_value'
				)
			);
		}
	}
	return $vars;
}

Here we are actually sorting our custom columns. First in line 5 we are making sure that we are viewing our post type (in this case, my custom post type cf_cats). If that has passed, we then check if orderby is set to one of our custom columns – either “age” or “toy” in my case. If orderby is set to “age”, then it orders the posts by the “age” column’s values numerically (notice '_cf_cat_age' from previous tutorials? Database key!). The same goes for the “toy” column as well, but alphabetically.

You’ll notice that the “age” column uses 'meta_value_num' while the “toy” column uses 'meta_value'. This is because we have age as a numerical value, and using 'meta_value' to sort numbers can have unexpected results. Use 'meta_value' for strings, and 'meta_value_num' for numbers.

And that’s it! I have added another cat to my list (though I only have one cat) for sorting. Here I have sorted the cats by toy as you can see by the arrows.

Sortable Columns

Questions? Comments? Leave them below!