For the same project as sorting custom post columns in WordPress admin, I also needed to add a sortable custom column in the Users (that’s users.php) page within the WordPress Admin. The custom column needed to show a custom author meta field.

I found a few tutorials online on this, and what I found was dead on in terms of adding the custom users column and adding content to it. Making the column sortable was another story… there were very few resources online and whatever I found just wouldn’t work.

When I reviewed the actual SQL queries WordPress was making, I realized they weren’t working because I was using WordPress with multisite enabled. The standard SQL query already did a JOIN of the usermeta table to the users table, but it did it to filter out users so that it returned only users of the current blog. Implementing the online tutorials did another LEFT JOIN, but they always resulted in an empty table. So, what I did was have WP do another JOIN, but with an alias – and that is working great!!

Note: Code works with WordPress 3.4.1, with multisite enabled.

Also, my custom author meta field is “church_name”.

And with that, here’s my code:

//add additional columns to the users.php admin page
function modify_user_columns($column) {
	$column = array(
		"cb" => "",
		"username" => "Username",
		"church" => "Church",//the new column
		"email" => "E-mail",
		"role" => "Role"
    return $column;

//add content to your new custom column
function modify_user_column_content($val,$column_name,$user_id) {
    $user = get_userdata($user_id);
	switch ($column_name) {
        case 'church':
            return $user->church_name;
		//I have additional custom columns, hence the switch. But am only showing one here
    return $return;

//make the new column sortable
function user_sortable_columns( $columns ) {
	$columns['church'] = 'church';
	return $columns;
add_filter( 'manage_users_sortable_columns', 'user_sortable_columns' );

//set instructions on how to sort the new column
if(is_admin()) {//prolly not necessary, but I do want to be sure this only runs within the admin
	add_action('pre_user_query', 'my_user_query');
function my_user_query($userquery){	
	if('church'==$userquery->query_vars['orderby']) {//check if church is the column being sorted
		global $wpdb;
		$userquery->query_from .= " LEFT OUTER JOIN $wpdb->usermeta AS alias ON ($wpdb->users.ID = alias.user_id) ";//note use of alias
		$userquery->query_where .= " AND alias.meta_key = 'church_name' ";//which meta are we sorting with?
		$userquery->query_orderby = " ORDER BY alias.meta_value ".($userquery->query_vars["order"] == "ASC" ? "asc " : "desc ");//set sort order