Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

I want to order my categories like I order my pages. I've added an extra field called Order to my taxonomy, but how do I order my terms by this value?

Adding and Saving my Order Value:

/** Add New Field To Category **/
function extra_category_fields( $tag ) {
    $t_id = $tag->term_id;
    $cat_meta = get_option( "category_$t_id" );
?>
<tr class="form-field">
    <th scope="row" valign="top"><label for="meta-order"><?php _e('Category Order'); ?></label></th>
    <td>
        <div id="catOrder">
            <input type="text" name="cat_meta[order]" size="3" style="width:5%;" value="<?php echo (isset($cat_meta['order'])) ? $cat_meta['order'] : '0'; ?>" />
        </div>
        <span class="description"><?php _e('Categories are ordered Smallest to Largest'); ?></span>
    </td> 
</tr>
<?php
}
add_action('protax_edit_form_fields','extra_category_fields');  

/** Save Category Meta **/
function save_extra_category_fileds( $term_id ) {
    if ( isset( $_POST['cat_meta'] ) ) {
        $t_id = $term_id;
        $cat_meta = get_option( "category_$t_id");
        $cat_keys = array_keys($_POST['cat_meta']);
            foreach ($cat_keys as $key){
            if (isset($_POST['cat_meta'][$key])){
                $cat_meta[$key] = $_POST['cat_meta'][$key];
            }
        }
        //save the option array
        update_option( "category_$t_id", strip_tags($cat_meta) );
    }
}
add_action ( 'edited_protax', 'save_extra_category_fileds');

Normally I could retrieve this value such as:

$categories = get_categories(array('taxonomy' => 'protax'));
foreach($categories as $cat){
    $tmp = get_option('category_'.$cat->cat_ID);
    echo $tmp['order'];
}

Is it possible to order by this custom value? Is there a better way to manually order my categories?

share|improve this question
1  
get_categories as an option to order by term_group. Term group is a field in wp_terms table that AFAIK is not used by WordPress. So you can use the extra field to set the term_group and then use 'orderby' => 'term_group' in $args array for get_categories. –  gmazzap Oct 8 '13 at 16:45
    
:/ I'm not sure I follow. When or where do I set term_group? –  Howdy_McGee Oct 8 '13 at 17:00
1  
$wpdb->update($wpdb->terms, array('term_group' => $cat_meta['order']), array('term_id'=>$term_id)); you need a WHERE clause and $cat_meta['order'] not all the $cat_meta array –  gmazzap Oct 8 '13 at 17:18
1  
In codex for get_categories orderby term_group is cited with any advice, but in codex for get_terms is said "not fully implemented (avoid using)" so isn't only your problem... sorry for your time loose, I remember I've used it with no problems... –  gmazzap Oct 8 '13 at 18:12
1  
No no, thank you for your help! I got it to work with get_categories - I was misspelling orderby: Solution is in my Question - again thank you for your help!!! –  Howdy_McGee Oct 8 '13 at 18:30

1 Answer 1

up vote 3 down vote accepted

SOLUTION - Updated: 03/03/2015 - Thanks to /u/G.M.

The below adds a new field to the Term Edit Page and saves the value into the un-used ( for the moment anyway ) term_group field which can then be used to order terms. In the below hooks ( actions ) you'll need to replace TAXONOMY_SLUG with your actual taxonomy slug.

/**
 * Append Fields To Term Edit Page
 * @param Term Object $term
 * @param string $taxonomy
 */
function term_order_field( $term, $taxonomy ) {
  ?>
    <tr class="form-field">
        <th scope="row" valign="top">
            <label for="meta-order"><?php _e( 'Category Order' ); ?></label>
        </th>
        <td>
            <input type="text" name="_term_order" size="3" style="width:5%;" value="<?php echo ( ! empty( $term->term_group ) ) ? $term->term_group : '0'; ?>" />
            <span class="description"><?php _e( 'Categories are ordered Smallest to Largest' ); ?></span>
        </td> 
    </tr>
  <?php
}
add_action( 'TAXONOMY_SLUG_edit_form_fields', 'term_order_field', 10, 2 );

/**
 * Save Term Order
 * @param int $term_id
 */
function save_term_order( $term_id ) {
    global $wpdb;

    if( isset( $_POST['_term_order'] ) ) {
        $wpdb->update( 
            $wpdb->terms,
            array(
                'term_group' => $_POST['_term_order']
            ),
            array( 
                'term_id'    => $term_id
            )
        );
    }
} // END Function
add_action( 'edited_TAXONOMY_SLUG', 'save_term_order' );

Add Term Order cell to Term List

/**
 * Add Column To Show 'Term Order' Field
 * @param array $columns
 * @return array $columns
 */
function term_order_header( $columns ) {
    $columns['order'] = '<center>Order</center>';
    return $columns;
}
add_filter( 'manage_edit-TAXONOMY_SLUG_columns', 'term_order_header' );

/**
 * Give 'Term Order' Column A Value `term_group`
 * @param string $empty
 * @param string $col_name
 * @param int $term_id
 * @return string
 */
function term_order_header_val( $empty = '', $col_name, $term_id ) {
    if( isset( $_GET['taxonomy'] ) && 'order' == $col_name ) {
        $term = get_term( $term_id, $_GET['taxonomy'] );
        return "<center>{$term->term_group}</center>";
    } else {
        return '0';
    }
}
add_filter( 'manage_TAXONOMY_SLUG_custom_column', 'term_order_header_val', 10, 3 );

Hook Documentation


Below is an out-dated solution that works better if you have multiple Term Meta Values you would like to save. If you only need to save Term Order, the above solution is best.

/** Add New Field To Category **/
function extra_category_fields( $tag ) {
    $t_id = $tag->term_id;
    $cat_meta = get_option( "category_$t_id" );
?>
<tr class="form-field">
    <th scope="row" valign="top"><label for="meta-order"><?php _e('Category Order'); ?></label></th>
    <td>
        <div id="catOrder">
            <input type="text" name="cat_meta[order]" size="3" style="width:5%;" value="<?php echo (isset($cat_meta['order'])) ? $cat_meta['order'] : '0'; ?>" />
        </div>
        <span class="description"><?php _e('Categories are ordered Smallest to Largest'); ?></span>
    </td> 
</tr>
<?php
}
add_action('protax_edit_form_fields','extra_category_fields');  

/** Save Category Meta **/
function save_extra_category_fileds( $term_id ) {
    global $wpdb;
    if ( isset( $_POST['cat_meta'] ) ) {
        $t_id = $term_id;
        $cat_meta = get_option( "category_$t_id");
        $cat_keys = array_keys($_POST['cat_meta']);
            foreach ($cat_keys as $key){
            if (isset($_POST['cat_meta'][$key])){
                $cat_meta[$key] = $_POST['cat_meta'][$key];
            }
        }
        update_option( "category_$t_id", $cat_meta );
        $wpdb->update($wpdb->terms, array('term_group' => $cat_meta['order']), array('term_id'=>$term_id));
    }
}
add_action ( 'edited_protax', 'save_extra_category_fileds');

Calling it:

$procats = get_categories(array('taxonomy' => 'protax', 'hide_empty' => 0, 'orderby' => 'term_group'));

Edit - You're also able to order them in the admin panel by using this filter:

function change_term_order( $orderby, $args, $taxonomies ) {
    if ( is_admin() && 'protax' !== $taxonomies[0] )
        return $args;

    $orderby = 'term_group';
    $args['order'] = 'ASC';
    return $orderby;
}
add_filter( 'get_terms_orderby', 'change_term_order', 10, 3 );
share|improve this answer
    
So I remember well :) +1 to reward your tenacity and my suggestion... –  gmazzap Oct 8 '13 at 19:10
    
Thanks for this. It convinced me to create a custom post type and link posts to taxonomy terms that hold the custom fields, as opposed to adding custom fields to the taxonomy itself. Without being able to use the loop for taxonomy terms the same way it works for posts, this would have been a real headache. –  cdonner Jun 12 '14 at 15:51

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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