Wordpress - Custom taxonomy, get_the_terms, listing in order of parent > child
There are probably some better ways to do this but you can always do a three simple foreach
loops.
I wrote an example function that does the job well and should serve you as a good starting point:
function print_taxonomic_ranks( $terms = '' ){
// check input
if ( empty( $terms ) || is_wp_error( $terms ) || ! is_array( $terms ) )
return;
// set id variables to 0 for easy check
$order_id = $family_id = $subfamily_id = 0;
// get order
foreach ( $terms as $term ) {
if ( $order_id || $term->parent )
continue;
$order_id = $term->term_id;
$order = $term->name;
}
// get family
foreach ( $terms as $term ) {
if ( $family_id || $order_id != $term->parent )
continue;
$family_id = $term->term_id;
$family = $term->name;
}
// get subfamily
foreach ( $terms as $term ) {
if ( $subfamily_id || $family_id != $term->parent )
continue;
$subfamily_id = $term->term_id;
$subfamily = $term->name;
}
// output
echo "Order: $order, Family: $family, Sub-family: $subfamily";
}
Let it live in your functions.php
file and use it in your templates like this:
print_taxonomy_ranks( get_the_terms( $post->ID, 'taxonomic_rank' ) );
NOTE: Looping the same array three times around sounds a bit stupid but on the other hand it's a quick and easy solution which is easy to read, extend and maintain.
Though Maugly's approach seem a bit more readable but running a loop 3 times over the array doesn't seem right to me. So here is just another approach which might be less readable for some but works without running loop 3 times.
function print_taxonomy_ranks( $terms ) {
// if terms is not array or its empty don't proceed
if ( ! is_array( $terms ) || empty( $terms ) ) {
return false;
}
foreach ( $terms as $term ) {
// if the term have a parent, set the child term as attribute in parent term
if ( $term->parent != 0 ) {
$terms[$term->parent]->child = $term;
} else {
// record the parent term
$parent = $term;
}
}
echo "Order: $parent->name, Family: {$parent->child->name}, Sub-Family: {$parent->child->child->name}";
}
I had a situation where a post could be tagged with multiple category groups, and multiple children within parent categories, so I wanted my hierarchy to reflect that. I also just wanted a few lines of code:
$terms = get_the_terms($id, 'department_categories');
foreach($terms as $key => $term){
if($term->parent != 0){
$terms[$term->parent]->children[] = $term;
unset($terms[$key]);
}
}
Basically after it finds a category's parent, it moves it to the parent's obj as a child, and then removes it from it's original position in the array. I've tested this using multiple siblings, children, and different levels of categories.
Hope someone else finds this useful in case they're just looking for some logic guidance rather than a "plugin"!