Quantcast
Channel: WordPress Dreamer » actions
Viewing all articles
Browse latest Browse all 3

How To Make Your WordPress Admin Columns Sortable

$
0
0

This tutorial is somewhat of an extension of Manage WordPress Posts Using Bulk Edit and Quick Edit which shows you how to add custom columns to take advantage of Quick Edit and Bulk Edit. All of the code is hanging out over at Github if you want to check it out.

Custom WordPress admin columns can be pretty helpful for quickly viewing, and managing, your content from the main edit screen. So why not take the action up a notch by making your columns sortable?

Well, first you have to have columns to sort. Most default columns are already sortable so we’re not gonna worry about them too much and, instead, focus on custom columns.

A column must be registered before it can be declared sortable. If you have not added/registered your custom column, check out steps #1 and #2 of my other tutorial before continuing.

  1. Register your columns as sortable
  2. Sorting the posts
  3. Download the code

Watch the tutorial

If you’d like to watch me walk through the steps to get your feet wet, check out the screencast below. If you can’t see the video or it isn’t working, you should be able to watch it here.

Unable to display content. Adobe Flash is required.

1) Register your columns as sortable

The most complicated part about registering your column as “sortable” is just figuring out the filter to use. It’s quite the mouthful: ‘manage_edit-{post_type}_sortable_columns’, where you, obviously, replace {post_type} with the name of the post type you’re editing. This filter allows you to filter the array of sortable column data.

In my example, like so many before, I’m working on a movie database so my post type is ‘movies’. Don’t forget that filters must ALWAYS return a value.

<?php
add_filter( 'manage_edit-movies_sortable_columns', 'my_website_manage_sortable_columns' );
function my_website_manage_sortable_columns( $sortable_columns ) {

   /**
    * In this scenario, I already have a column with an
    * ID (or index) of 'release_date_column'. Both column 
    * indexes MUST match.
    * 
    * The value of the array item (after the =) is the
    * identifier of the column data. For example, my
    * column data, 'release_date', is a custom field
    * with a meta key of 'release_date' so my
    * identifier is 'release_date'.
    */
   $sortable_columns[ 'release_date_column' ] = 'release_date';

   // Let's also make the film rating column sortable
   $sortable_columns[ 'film_rating_column' ] = 'film_rating';

}
?>

Now, when you hover over your column headers, you should see little arrows pop up. This means sorting has been enabled.

admin-sortable-columns-arrow

Yay sorting! But wait! There’s one more step!

2) Sorting the posts

Now, just because we’ve registered our sortable columns doesn’t mean the posts will actually sort by our column data. Wouldn’t that be nice. No, we still have to talk to the posts query and set up the sorting.

There are two ways to approach this step. If your data sorting is a simple alphabetical or numerical sort, like our film rating, check out option A. If your sort is more complicated, like our release date which is a date string stored in a custom field, check out option B.

Option A: “My data sorting is a simple alphabetical or numerical sort”

Then it’s your lucky day because sorting should be simple. All you need to do is take advantage of the ‘pre_get_posts’ action to access, and edit, the main WP query.

In our example, we’ll be sorting by our custom field ‘film_rating’, which is a simple alphabetical sort. Check out the Order and Orderby Parameters of the WP Query to see what values you need to change to sort your posts your column data.

<?php
add_action( 'pre_get_posts', 'manage_wp_posts_be_qe_pre_get_posts', 1 );
function manage_wp_posts_be_qe_pre_get_posts( $query ) {

   /**
    * We only want our code to run in the main WP query
    * AND if an orderby query variable is designated.
    */
   if ( $query->is_main_query() && ( $orderby = $query->get( 'orderby' ) ) ) {

      switch( $orderby ) {

         // If we're ordering by 'film_rating'
         case 'film_rating':

            // set our query's meta_key, which is used for custom fields
            $query->set( 'meta_key', 'film_rating' );
				
            /**
             * Tell the query to order by our custom field/meta_key's
             * value, in this film rating's case: PG, PG-13, R, etc.
             *
             * If your meta value are numbers, change 'meta_value'
             * to 'meta_value_num'.
             */
            $query->set( 'orderby', 'meta_value' );
				
            break;

      }

   }

}
?>

Option B: “My data sorting is more complicated and needs to be queried manually”

If your column data is a little more complicated, like combining several values or a custom field that’s a date, you’ll have to use the ‘posts_clauses’ filter to manually tweak the WP Query clauses.

For the example below, we’ll be setting up the sort for our ‘release_date’ which is a date string stored in a custom field. The reason this sort will not work with the “out of the box” WP Query is because option A will only order alphabetically and numerically.

Don’t forget that filters must ALWAYS return a value.

<?php
add_filter( 'posts_clauses', 'manage_wp_posts_be_qe_posts_clauses', 1, 2 );
function manage_wp_posts_be_qe_posts_clauses( $pieces, $query ) {
   global $wpdb;

   /**
    * We only want our code to run in the main WP query
    * AND if an orderby query variable is designated.
    */
   if ( $query->is_main_query() && ( $orderby = $query->get( 'orderby' ) ) ) {

      // Get the order query variable - ASC or DESC
      $order = strtoupper( $query->get( 'order' ) );

      // Make sure the order setting qualifies. If not, set default as ASC
      if ( ! in_array( $order, array( 'ASC', 'DESC' ) ) )
         $order = 'ASC';

      switch( $orderby ) {
	
         // If we're ordering by release_date
         case 'release_date':
			
            /**
             * We have to join the postmeta table to
             * include our release date in the query.
             */
            $pieces[ 'join' ] .= " LEFT JOIN $wpdb->postmeta wp_rd ON wp_rd.post_id = {$wpdb->posts}.ID AND wp_rd.meta_key = 'release_date'";
				
            // Then tell the query to order by our custom field.
            // The STR_TO_DATE function converts the custom field
            // to a DATE type from a string type for
            // comparison purposes. '%m/%d/%Y' tells the query
            // the string is in a month/day/year format.
            $pieces[ 'orderby' ] = "STR_TO_DATE( wp_rd.meta_value,'%m/%d/%Y' ) $order, " . $pieces[ 'orderby' ];
				
         break;
		
      }
	
   }

   return $pieces;

}
?>
Now our movies are sorted by release date. Isn't that nice.

Now our movies are sorted by release date. Isn’t that nice.

Download the code

Well, folks, that’s all she wrote (for now). Obviously there are TONS of different scenarios for column data and sorting and there’s just no way to cover them all but I’ll try to add to the tutorial if an example strikes my fancy.

The code for this tutorial is part of my http://wpdreamer.com/2012/03/manage-wordpress-posts-using-bulk-edit-and-quick-edit/ project so head on over to Github to download the code. Thanks!


Viewing all articles
Browse latest Browse all 3

Latest Images

Trending Articles





Latest Images