Sort users by numeric value in Users Screen
By default you can sort users in Users Screen by username, name, email and role.
What if we wanted to sort users based on numeric value? Value can be for example age or expire date. First we’d need to save numeric info in *_usermeta
table. There are handy functions like add_user_meta and update_user_meta for doing that. But it’s outside of this tutorial. Let’s focus on how you can manage custom sortable columns and sort by meta_value_num
.
There are four steps we need to take:
- Add new custom user column using manage_users_columns.
- Add content to column using
manage_users_custom_column
. - Make custom column sortable using
manage_users_sortable_columns
. - Sort users based on numeric value in custom column using
pre_get_users
.
Add custom column
Let’s use expire date, which is stored as strtotime
, as an example. First we add custom column using manage_users_columns
filter.
/** * Add new user column: Expire Date. * * @since 1.0.0 * @return array $columns */ function prefix_expire_date_column( $columns ) { $columns['expire_date'] = __( 'Expire Date', 'text-domain' ); return $columns; } add_filter( 'manage_users_columns', 'prefix_expire_date_column' );
We add new column in users columns array in format name => label
. In our case custom column name is expire_date. Let’s keep that in mind.
Add content to custom column
Next step is to add content in our custom column. We can do that using manage_users_custom_column
filter. It has three parameters: $value
, $column_name
and $user_id
.
/** * Adds Expire date and Status to column. * * @since 1.0.0 * @return void */ function prefix_add_custom_columns( $value, $column_name, $user_id ) { if( 'expire_date' == $column_name ) { /* Get expire date somehow. For example using your custom function */ $expire_date = prefix_get_expire_date( $user_id ); $value = $expire_date; } return $value; } add_action( 'manage_users_custom_column', 'prefix_add_custom_columns', 10, 3 );
We want to add and return expire date value when our custom column name is the correct one, in our example it was expire_date
. In short we first check that our column name is expire_date
, then add your content and return the value.
Make custom column sortable
By default custom column is not sortable. Next we use manage_users_sortable_columns
filter to make our custom column sortable.
/** * Add sortable columns. * * @since 1.0.0 * @return void */ function prefix_sortable_columns( $columns ) { $columns['expire_date'] = 'expire_date'; return $columns; } add_filter( 'manage_users_sortable_columns', 'prefix_sortable_columns' );
We use our expire_date
column again and I prefer to give it the same name. It tells WordPress that our orderby parameter is expire_date
and when you click the Expire date column our URL turns into this: users.php?orderby=expire_date&order=asc
.
But the last step is the most important one.
Sort users based on numeric value
Even if we make custom columns sortable nothing really happens when you click the Expire date column. We have to tell WordPress how we want to sort. In WordPress 4.2 sorting by numeric value became much more easier in WP_User_Query
. Here is core track ticket for more info.
It means that now we can use meta_value_num
in orderby
parameter (orderby=meta_value_num
).
In the same time, or in WordPress 4.0.0, there is action hook called pre_get_users
which we can use to sort based on numeric value in our custom user column.
/** * Sort by expire date. Meta key is called 'prefix_expiration_date'. * * @since 1.0.0 * @return void */ function prefix_sort_by_expiration_date( $query ) { if ( 'expire_date' == $query->get( 'orderby' ) ) { $query->set( 'orderby', 'meta_value_num' ); $query->set( 'meta_key', 'prefix_expiration_date' ); } } add_action( 'pre_get_users', 'prefix_sort_by_expiration_date' );
We need three things for sorting:
- Firts check that our query orderby paramater is
expire_date
. Note that this could be named for something else but in our case it was the same as column name. We useget()
method for retrieving query variable. - Set
orderby=meta_value_num
because we wanted to sort by numeric value. We useset()
method for setting the parameter. - Set
meta_key=your_meta_key_name
. In our examplemeta_key
is calledprefix_expiration_date
. In here we also useset()
method.
You can check all the methods and properties in WP_User_Query codex page.
That’s it. We’re done.
Conclusion
It took me about two days to figure this out when I needed this feature in EDD Members add-on. Believe me, I tried everything and read every tutorial I could find. But still no luck. Then I did what I was suppose to do in the first place.
- Ask help from Justin Tadlock in Themehybrid forums. I could have asked help in WordPress Stackexchange but I had a hunch that he’s been working on the same issue. And he did.
- Dive in to the Core code. We would have never found the hook
pre_get_users
if it wasn’t right there in the Core code.
Justin also have excellent tutorial about Custom columns for custom post types.