Control term order on a per-post basis

I’m not sure if I understand exactly what your trying to accomplish but I’ve outlined a way for you to sort the order of terms associated with the current post.

Html for the term order metabox:

 echo '<ul id="the-terms">'
         $terms = get_the_terms( $post->ID, $taxonomy );
            foreach ( $terms as $term ) {
            echo '<li class="item" id="term-'.$term->term_id.'">'. $term->name .'</li>';        
            }
            echo '</ul>';
            echo '<a href="https://wordpress.stackexchange.com/questions/38961/javascript: void(0); return false;" id="save_term_order" class="button-primary">Update Order</a>';

Javascript to make the above list sortable and save the order using ajax.

*Note: requires jQuery UI-Sortable.

jQuery(document).ready(function() {  
// Make the term list sortable
        jQuery("#the-terms").sortable({
            items: '.item',
            placeholder: 'sortable-placeholder',
            tolerance: 'pointer',
            distance: 1,
            forcePlaceholderSize: true,
            helper: 'clone',
            cursor: 'move'
        });
// Save the order using ajax        
   jQuery("#save_term_order").live("click", function() {
        var postID = $("#post_ID").val();
        jQuery.post(ajaxurl, {
        action:'save_term_order', 
        cache: false, 
        post_id: postID,  
        order: jQuery("#the-terms").sortable('toArray').toString(),
        success: ajax_response()
       });
            return false; 
    });   
 });

WordPress ajax function to save the order as a custom field:

add_action ( 'wp_ajax_save_term_order', 'term_order_save' );
function term_order_save () {
    global $wpdb;
    $wpdb->flush ();
    $item_id = $_POST['post_id'];
    $meta_key = '_term_order';

    $order = $_POST[ 'order' ];
    $str = str_replace ( "term-", "", $order );
    $int = str_replace ( "'", "", $str );

    update_post_meta ( $item_id, $meta_key, array ( 'term_order' => $int ) );

    $response="<p>Term order updated</p>";
    echo $response;

    die(1);
}

This will save a list of the term id’s in order sorted as a serialized array:

_term_order => array(
term_order => ‘123,312,110,34,44,27’
)

To show the list of ordered terms on the front end:

$orderd_terms = get_post_meta ( $post->ID, '_term_order', true );
$terms = $ordered_terms[ 'term_order' ];
$term_ids = explode ( ",", $terms );

  for ( $i = 0; $i < count ( $term_ids ); $i ++ ) {

      $term = get_term( $term_ids[$i], $taxonomy, OBJECT)
      echo $term->name;
  }

Leave a Comment