In a recent article by Claudio Simeone, he demonstrated how you could add extra columns to your post, or custom post type, admin screens (or remove existing ones). In this quick tip I build on that by showing you how to make your newly created columns sortable.
To tell WordPress which columns you want to register as sortable you need this filter:
manage_{$screen->id}_sortable_column
For posts and pages, $screen->id
is 'edit-post' and 'edit-page' respectively. In general, for a post type with name 'my-post-type', it is 'edit-my-post-type'.
The filter passes an array with the names of sortable columns as keys, and what to order by as a value. More precisely, the values dictate what the 'orderby
' parameter is set as in the query that populates the table. In the same way that you can remove columns, you can also make columns 'unsortable' by removing them from this array. Let's see an example:
Register a Column
Following Claudio's article, suppose we've added the column 'slices' to our 'cake' post type, which we can do as follows:
add_filter('manage_edit-cake_columns', 'my_extra_cake_columns'); function my_extra_cake_columns($columns) { $columns['slices'] =__('Slices','myplugindomain'); return $columns; }
And we've added the content for the column as follows:
add_action( 'manage_cake_posts_custom_column', 'my_cake_column_content', 10, 2 ); function my_cake_column_content( $column_name, $post_id ) { if ( 'slices' != $column_name ) return; //Get number of slices from post meta $slices = get_post_meta($post_id, 'slices', true); echo intval($slices); }
I've stored slices as post meta, but your columns can be populated by other data.
Make a Column Sortable
Now we register our custom column as 'sortable'. As mentioned above we use the manage_{$screen->id}_sortable_column
filter. The $screen->id
in this case is 'edit-cake'.
add_filter( 'manage_edit-cake_sortable_columns', 'my_sortable_cake_column' ); function my_sortable_cake_column( $columns ) { $columns['slices'] = 'slice'; //To make a column 'un-sortable' remove it from the array //unset($columns['date']); return $columns; }
The key of the $columns
array indicates a sortable column, and its value tells WordPress what to set 'orderby
' to in the query. If that value was one of the 'orderby
's natively understood by WordPress (these include 'title
', 'date
', 'modified
', 'comment_count
', or indeed any of the others listed under WP_Query in the WordPress Codex) we could stop here. The exception to this rule, as in this example, is the 'meta_value
' and 'meta_value_num
' parameters, which require us to set a meta key as well.
If we want to sort by a meta value, or by some other way WordPress doesn't automatically understand you have to tell it what you mean by ordering by 'slice'. If you are ordering by post meta, the easiest way to do this is to hook onto the pre_get_posts
action. This passes a query object which we can modify. Note, that this action is fired for all default queries (front and back). While it's unlikely to cause any problems, unless you want WordPress to interpret orderby
set to 'slice' on the front end as well, it's a good idea to only effect queries on the admin side.
add_action( 'pre_get_posts', 'my_slice_orderby' ); function my_slice_orderby( $query ) { if( ! is_admin() ) return; $orderby = $query->get( 'orderby'); if( 'slice' == $orderby ) { $query->set('meta_key','slices'); $query->set('orderby','meta_value_num'); } }
This checks if our query is ordering by 'slice' and if it is, it tells WordPress to numerically order by the value of the 'slices' post meta. If you want to sort the value alphabetically then use 'meta_value
' rather than 'meta_value_num
'.
$query
is a WP_Query
object, so anything you can sort by using that object, you can sort your columns by. For anything else more complicated, you will need to hook into the posts_orderby
(or post_clauses
) hook, but that's out of the scope of this quick tip.
Note: If a post doesn't have a value stored for that meta key then it will not appear when you sort by that meta key. This is different from a post having 0 stored as the meta value.
Comments