I have a custom post type named domicile
. Each post (domicile) has an owner (not the author). Owners are users with a custom role. I store the user id as a post meta value (dmb_owner
) for the domicile
post type.
How do I sort the list table (wp-admin/edit.php?post_type=domicile
) by the display names of owners?
The relevant code from my class, setup_columns()
is called on init
:
/**
* Manage columns for List Table.
*
* @wp-hook init
* @return void
*/
protected function setup_columns()
{
add_filter(
"manage_edit-{$this->post_type}_columns",
array ( $this, 'set_column_header' )
);
add_action(
"manage_{$this->post_type}_posts_custom_column",
array ( $this, 'render_columns' ),
10,
2
);
add_filter(
"manage_edit-{$this->post_type}_sortable_columns",
array ( $this, 'set_sortable_columns' )
);
add_filter(
'request',
array ( $this, 'prepare_orderby' )
);
}
/**
* Register column headers.
*
* @wp-hook manage_edit-{$this->post_type}_columns
* @param array $columns
* @return array
*/
public function set_column_header( $columns )
{
unset (
$columns['author'],
$columns['comments'],
$columns['date']
);
$columns['owner'] = __( 'Owner', 't5_domicile_manager' );
return $columns;
}
/**
* Display cell content.
*
* @wp-hook manage_{$this->post_type}_posts_custom_column
* @param string $column_name
* @param int $post_id
* @return void
*/
public function render_columns( $column_name, $post_id = 0 )
{
if ( 'owner' === $column_name )
{
$owner_id = get_post_meta( $post_id, 'dmb_owner', TRUE );
if ( $owner_id )
{
$owner = get_user_by( 'id', $owner_id );
print $owner ? $owner->display_name : '<i>not set</i>';
}
}
}
/**
* Register sortable columns
*
* @wp-hook manage_edit-{$this->post_type}_sortable_columns
* @param array $columns
* @return array
*/
public function set_sortable_columns( $columns )
{
$columns['owner'] = 'owner';
return $columns;
}
/**
* Set custom sort order.
*
* @wp-hook request
* @param array $vars
* @return array
*/
public function prepare_orderby( $vars )
{
if ( isset ( $vars['orderby'] ) && 'owner' == $vars['orderby'] )
{
$vars = array_merge(
$vars,
array (
'meta_key' => 'dmb_owner',
'orderby' => 'meta_value_num'
)
);
}
return $vars;
}
This ⦠works, but it is obviously wrong, because it sorts by the stored ID. I have to filter the query â but I am not sure how exactly I should do that.
Sorry for the title, but I want to make sure this will be found. I searched very hard and found nothing useful.
An ‘easy’ but not very good solution is to store the user’s display name as well as ID, and sort by that. Obviously an update of a user’s display name would prompt an update of all the domicile that user owns.
Alternatively the following is an outline (untested) of what should work. The idea is to tell WordPress to sort by the meta value still (so that WordPress joins the post meta table) and then its possible to use the
post_clauses
filter to join theusers
table and sort by display name:You can add the custom field
dmb_owner
to the query in backend and then you can filter about this with your standard filters.Now is this custom field inside the
$query_vars
and can usable, like your methodprepare_orderby()
.