4

I've created custom taxonomy called 'cities' where you can add cities and added custom field ( radio button ) with 2 options: 'Yes' and 'No' ( never mind what that is ). Everythins is ok, I can get that value and other stuff.

Later on I came with idea to add a sortable column ( Like 'Name', 'Slug', 'Posts' etc. ). I've managed to create that column, make it sortable but don't know how to sort those cities by that custom field? Right now it's sorting by name, because I can't get it to work with custom field.

Any clues/hints maybe?

2
  • How have you added the custom field? Commented Aug 27, 2014 at 16:32
  • with ACF plugin.
    – mihajlo
    Commented Aug 27, 2014 at 16:33

5 Answers 5

11

I had a similar problem and managed to solve it. In my case I have a custom taxonomy, issue, which contains a required date picker custom field using the ACF PRO plugin—the field name is issue_date. I wanted to add the date column to my issue edit screen at wp-admin/edit-tags.php?taxonomy=issue and I wanted to allow admins to sort issues by date.

I tried hooking into pre_get_posts as @aifrim answered above, but that action is not part of the query that runs when WordPress loads taxonomy terms into the edit screen. Furthermore, taxonomy terms don't have any native metadata in the WordPress database so a meta_query will not work because my metadata is stored in another table altogether. A fun curveball.

Step 1: Create the new column itself, it will be empty initially

function create_date_column_for_issues($issue_columns) {
  $issue_columns['date'] = 'Date';
  return $issue_columns;
}
add_filter('manage_edit-issue_columns', 'create_date_column_for_issues');

Step 2: Populate the new column

function populate_date_column_for_issues($value, $column_name, $term_id) {
  $issue = get_term($term_id, 'issue');
  $date = DateTime::createFromFormat('Ymd', get_field('issue_date', $issue));
  switch($column_name) {
    case 'date': 
      $value = $date->format('Y/m/d');
    break;
    default:
    break;
  }
  return $value;    
}
add_filter('manage_issue_custom_column', 'populate_date_column_for_issues', 10, 3);

Step 3: Make the new column sortable

function register_date_column_for_issues_sortable($columns) {
  $columns['date'] = 'issue_date';
  return $columns;
}
add_filter('manage_edit-issue_sortable_columns', 'register_date_column_for_issues_sortable');

Step 4: Define the custom sorting (where the magic happens)

function sort_issues_by_date($pieces, $taxonomies, $args) {
  global $pagenow;
  if(!is_admin()) {
    return $pieces;
  }

  if(is_admin() && $pagenow == 'edit-tags.php' && $taxonomies[0] == 'issue' && (!isset($_GET['orderby']) || $_GET['orderby'] == 'issue_date')) {
    $pieces['join']   .= " INNER JOIN wp_options AS opt ON opt.option_name = concat('issue_',t.term_id,'_issue_date')";
    $pieces['orderby'] = "ORDER BY opt.option_value";
    $pieces['order']   = isset($_GET['order']) ? $_GET['order'] : "DESC";
  }

  return $pieces;
}
add_filter('terms_clauses', 'sort_issues_by_date', 10, 3);

My conditional statement in step 4 will also sort descending by issue_date as the default sorting when there is no other sorting criteria set.

I hope this helps someone else looking to make a better admin experience!

2
  • 3
    I'm surprised this doesn't have more upvotes. It's a very helpful answer.
    – John Conde
    Commented Apr 6, 2019 at 21:07
  • Brilliant answer! Commented Oct 29, 2022 at 16:16
7

Many thanks to @cfx for this answer. Now that WP has Term Meta support, I updated Step 4 to take advantage of that. This solution borrows from this answer https://wordpress.stackexchange.com/a/246206/85388 which shows how to connect a meta_query to an orderby.

add_filter('pre_get_terms', 'uh_service_type_taxonomy__orderby');
function uh_service_type_taxonomy__orderby( $term_query ) {
  global $pagenow;
  if(!is_admin()) {
    return $term_query;
  }
  // WP_Term_Query does not define a get() or a set() method so the query_vars member must
  // be manipulated directly
  if(is_admin() && $pagenow == 'edit-tags.php' && $term_query->query_vars['taxonomy'][0] == 'uh_service_type_taxonomy' && (!isset($_GET['orderby']) || $_GET['orderby'] == 'term_order')) {
    // set orderby to the named clause in the meta_query
    $term_query->query_vars['orderby'] = 'order_clause';
    $term_query->query_vars['order'] = isset($_GET['order']) ? $_GET['order'] : "DESC";
    // the OR relation and the NOT EXISTS clause allow for terms without a meta_value at all
    $args = array('relation' => 'OR',
      'order_clause' => array(
        'key' => 'taxonomy_term_order',
        'type' => 'NUMERIC'
      ),
      array(
        'key' => 'taxonomy_term_order',
        'compare' => 'NOT EXISTS'
      )
    );
    $term_query->meta_query = new WP_Meta_Query( $args );
  }
  return $term_query;
}
0

A custom field is a custom post meta data made by the user or a theme/plugin, in this case that custom field is named yesno.

To add a column for it to posts or custom post types (myposttype):

add_filter('manage_edit-myposttype_columns', 'my_custom_columns');
function my_custom_columns($columns) {
    $columns['yesno'] = 'Yes/No';
    return $columns;
}

This is how you make the newly added column sortable:

add_filter('manage_edit-myposttype_sortable_columns', 'my_sortable_columns');
function my_sortable_columns($columns)
{
    $columns['yesno'] = 'yesno';
    return $columns;
}

And this is how you sort it

add_action('pre_get_posts', 'sort_my_posts');
function sort_my_posts($query)
{
    if (!is_admin())
        return;
    $orderby = $query->get('orderby');
    if ($orderby == 'yesno') {
        $query->set('meta_key', 'yesno');
        $query->set('orderby', 'yesno');
    }
}

And it will sort them asc or desc for the Yes or No values that are saved in the meta data.

Is this what you have been looking for?

2
  • Sorry for answering this late after your post, but in the mean time I moved to the new project and fixed this with jQuery but I will bookmark this link ( I believe I'll encounter the same problem once again ) and answer after I try this code.
    – mihajlo
    Commented Sep 9, 2014 at 8:03
  • @mihajloWR please let me know of the problems you will encounter because I see myself in the future in need of such a code.
    – aifrim
    Commented Sep 9, 2014 at 8:51
0

for me, I made a custom taxonomy and in that custom taxonomy I had a custom meta. I wanted to have in the admin backend a column and made it sortable. to make sortable work for a custom taxonomy in a custom meta I did this.

https://pastebin.com/vr2sCKzX

public function pre_get_terms( $query ) {
    $meta_query_args = array(
        'relation' => 'AND', // Optional, defaults to "AND"
        array(
            'key'     => 'order_index',
            'value'   => 0,
            'compare' => '>='
        )
    );
    $meta_query = new WP_Meta_Query( $meta_query_args );
    $query->meta_query = $meta_query;
    $query->orderby = 'position_clause';
}

I found the answer in this link https://core.trac.wordpress.org/ticket/34996

I just had to adapt the answer provided in the comments by @eherman24

0

For admin taxonomy table sortable column it's perfect solution. Add any custom field in specific term so this field value column sorting . Also add this code in your active theme's functions.php file. enter image description here

add_filter( 'manage_edit-{taxonomy-name}_sortable_columns' ), 'callback_term_sortable_columns_func'));
 function callback_term_sortable_columns_func( $columns ) 
    {
        $columns['column-name'] = 'column-name';
        return $columns;
    }
add_filter('pre_get_terms', 'callback_filter_terms_clauses');
function callback_filter_terms_clauses( $term_query ) 
    {
        global $pagenow;
        if(!is_admin()) { return $term_query; }
        if(is_admin() && $pagenow == 'edit-tags.php' && (!isset($_GET['orderby']) || $_GET['orderby'] == 'column-name')) 
        {
            $term_query->query_vars['orderby'] = 'meta_value';
            $term_query->query_vars['order'] = isset($_GET['order']) ? $_GET['order'] : "DESC";
            $args = array('relation' => 'OR',
                            'order_clause' => array(
                                'key' => '{term_meta_key}',
                                'type' => 'STRING'
                            ),
                            array(
                                'key' => 'taxonomy_term_order',
                                'compare' => 'NOT EXISTS'
                            ),
                            array(
                                'key' => 'taxonomy_term_order',
                                'compare' => '='
                            )
                        );
            $term_query->meta_query = new WP_Meta_Query( $args );
        }
        return $term_query;
    }
2
  • Please edit your answer, and add an explanation: why could that solve the problem? Explain your code.
    – fuxia
    Commented Nov 17, 2021 at 18:57
  • Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.
    – Community Bot
    Commented Nov 20, 2021 at 13:41

Your Answer

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

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