16

I have a added custom column to a custom post type, and it works fine. I just want it to sort the names by title, so I tried this,

function sortable_custom_columns( $columns ) {
    $columns['custom_column'] = 'title';
    return $columns;
}
add_filter( 'manage_edit-custom_sortable_columns', 'sortable_custom_columns' );

However, that is returning very random sorting. I think it may have to do with the content of the column? Which I render like this;

function location_column_content( $column, $post_id ) {
    switch ( $column ) {
        case 'practice_name':
            $location_post_meta = get_post_meta( $post_id );
            $practice_post_id = $location_post_meta['practice_id'][0];
            echo '<a href="' . get_edit_post_link( $practice_post_id ) . '">' . get_the_title( $practice_post_id ) . '</a>';
            break;
    }

}
add_action( 'manage_sf-location_posts_custom_column', 'location_column_content', 10, 2 );

Does this make sense? Any thoughts here? Thank you

2
  • What if I'm using an item value? ex. $item->get_meta( '_st_check_in' ); How would you sort it? Feb 9, 2021 at 17:30
  • @DanielMuñoz do not post a comment reply as the solution to the question. I understand you only have 1 reputation and can't comment on other peoples questions yet but that is no excuse for spamming the site. If you continue the automated systems will flag you as a spammer and ban you. I couldn't figure out what you meant to comment on so I moved it to the question itself
    – Tom J Nowell
    Feb 9, 2021 at 18:03

3 Answers 3

35

Make sure to change MY_POST_TYPE, MY_CUSTOM_COLUMN and MY_META_KEY to the actual values.

First, add your custom column. Unset the date and set it again to keep it in the last column. You can skip this step.

<?php
function my_manage_MY_POST_TYPE_columns( $columns )
{
    // save date to the variable
    $date = $columns['date'];
    // unset the 'date' column
    unset( $columns['date'] ); 
    // unset any column when necessary
    // unset( $columns['comments'] );

    // add your column as new array element and give it table header text
    $columns['MY_CUSTOM_COLUMN'] = __('Custom Column Header Text');

    $columns['date'] = $date; // set the 'date' column again, after the custom column

    return $columns;
}
?>

Second, make your column sortable using manage_edit-{$post_type}_sortable_columns filter (not documented yet).

<?php
function my_set_sortable_columns( $columns )
{
    $columns['MY_CUSTOM_COLUMN'] = 'MY_CUSTOM_COLUMN';
    return $columns;
}
?>

Third, populate column cells.

<?php
function my_populate_custom_columns( $column, $post_id )
{
    switch ( $column ) {
        case 'MY_CUSTOM_COLUMN':
            echo get_post_meta($post_id, 'MY_META_KEY', true);
            break;
        case 'MAYBE_ANOTHER_CUSTOM_COLUMN':
            // additional code
            break;
    }
}
?>

Now you are ready to actually sort that column.

Note: if you don't check meta_query for empty (non-existent) values, your column will show only the posts having (non-empty) meta value until it will be sorted by another by default or another column

<?php
function my_sort_custom_column_query( $query )
{
    $orderby = $query->get( 'orderby' );

    if ( 'MY_CUSTOM_COLUMN' == $orderby ) {

        $meta_query = array(
            'relation' => 'OR',
            array(
                'key' => 'MY_META_KEY',
                'compare' => 'NOT EXISTS', // see note above
            ),
            array(
                'key' => 'MY_META_KEY',
            ),
        );

        $query->set( 'meta_query', $meta_query );
        $query->set( 'orderby', 'meta_value' );
    }
}
?>

And now let's apply filters and actions. Check if you are not on the front-end, on the right page and the right post type is chosen:

<?php
global $pagenow;

if ( is_admin() && 'edit.php' == $pagenow && 'MY_POST_TYPE' == $_GET['post_type'] ) {

    // manage colunms
    add_filter( 'manage_MY_POST_TYPE_posts_columns', 'my_manage_MY_POST_TYPE_columns' );

    // make columns sortable
    add_filter( 'manage_edit-MY_POST_TYPE_sortable_columns', 'my_set_sortable_columns' );

    // populate column cells
    add_action( 'manage_MY_POST_TYPE_posts_custom_column', 'my_populate_custom_columns', 10, 2 );

    // set query to sort
    add_action( 'pre_get_posts', 'my_sort_custom_column_query' );
}

?>
4
  • This still works perfectly as of today.
    – MattFisch
    Feb 2, 2022 at 14:35
  • manage_edit-{$post_type}_sortable_columns is documented as manage_{$this->screen->id}_sortable_columns, where $this->screen->id in this case refers to edit-post, edit-page or edit-<post_type>.
    – KittMedia
    May 6, 2022 at 8:19
  • An alternative to using a meta_query is to simply use $query->set( 'meta_key' , 'MY_META_KEY' );. This will avoid the exist/not exists problem.
    – Jared
    Dec 21, 2022 at 15:11
  • If the values in your custom column are numbers, you will probably want to use $query->set( 'orderby', 'meta_value_num' ) instead of $query->set( 'orderby', 'meta_value' ). Sep 8 at 12:12
2

Make Columns Sortable

By default the new custom columns are not sortable so this makes it hard to find data that you need. To sort the custom columns WordPress has another filter manage_edit-post_sortable_columns you can use to assign which columns are sortable.

When this action is ran the function will pass in a parameter of all the columns which are currently sortable, by adding your new custom columns to this list will now make these columns sortable. The value you give this will be used in the URL so WordPress understands which column to order by.

The following to allow you to sort by the custom column meta.

// Register the column as sortable
function register_sortable_columns( $columns ) {
    $columns['meta'] = 'Custom Column';
    return $columns;
}
add_filter( 'manage_edit-post_sortable_columns', 'register_sortable_columns' );
1
  • I appreciate the effort you've put into the description here! But the solution as-is seems to reiterate a piece of code which is already mentioned in the question as ineffectual to their objective
    – bosco
    Jun 22, 2021 at 18:49
-2

you need sort table using pre_get_posts. Nice step-by-step instructions on envato tips

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.