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'm current using the following code to echo the categories of my post :

<?php foreach((get_the_category()) as $category) { echo $category->cat_name . ' '; } ?> 

So, for example, I have post with a parent category HOBBIES and a sub category MUSIC. When this code is used, it is displayed as

MUSIC HOBBIES

While I want to display it as,

HOBBIES MUSIC

How can i achieve this? BTW, the cat id for hobbies is 7 and cat id for jazz is 8.

share|improve this question
add comment

1 Answer 1

This is a tricky and interesting one. It would be pretty easy to write hardcoded orders for a whitelist of categories, but a true ordering algorithm - which will handle an arbitrary number of categories, and an arbitrary tree depth - requires recursion. What follows probably is not the most efficient solution possible, but it works to order a list of categories of no matter what length or depth:

$categories = get_the_category();

// Assemble a tree of category relationships
// Also re-key the category array for easier
// reference
$category_tree = array();
$keyed_categories = array();

foreach( (array)$categories as $c ) {
    $category_tree[$c->cat_ID] = $c->category_parent;
    $keyed_categories[$c->cat_ID] = $c;
}

// Now loop through and create a tiered list of
// categories
$tiered_categories = array();
$tier = 0;

// This is the recursive bit
while ( !empty( $category_tree ) ) {
    $cats_to_unset = array();
    foreach( (array)$category_tree as $cat_id => $cat_parent ) {
        if ( !in_array( $cat_parent, array_keys( $category_tree ) ) ) {
            $tiered_categories[$tier][] = $cat_id;
            $cats_to_unset[] = $cat_id;
        }
    }

    foreach( $cats_to_unset as $ctu ) {
        unset( $category_tree[$ctu] );
    }
    $tier++;
}

// Walk through the tiers to order the cat objects properly
$ordered_categories = array();
foreach( (array)$tiered_categories as $tier ) {
    foreach( (array)$tier as $tcat ) {
        $ordered_categories[] = $keyed_categories[$tcat];
    }
}

// Now you can loop over them and do whatever you want
foreach( (array)$ordered_categories as $oc ) {
    echo $oc->cat_name . ' ';
}

Note that, if get_the_category() returns multiple categories with the same parent, this algorithm treats them the same (which is to say that they are placed in the same order in which get_the_category() returns them).

share|improve this answer
    
doesn't work. i get an error "Warning: Invalid argument supplied for foreach()". –  user1178152 Mar 24 '12 at 16:14
1  
That warning is not what's causing it not to work; the warning just means that somewhere along the line, an array is ending up empty. I have amended the code above so that the warning should be avoided, but I'm afraid you'll have to do more meaningful debugging in order for me to give you a better sense of where things are going wrong. –  Boone Gorges Mar 24 '12 at 16:33
add comment

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.