<?php
/**
* Recursively get taxonomy and its children
*
* @param string $taxonomy Taxonomy slug.
* @param int $parent Parent term id.
* @return array
*/
function get_taxonomy_hierarchy( $taxonomy, $parent = 0 ) {
// Only 1 taxonomy.
$taxonomy = is_array( $taxonomy ) ? array_shift( $taxonomy ) : $taxonomy;
// Get all direct descendants of the $parent.
$terms = get_terms( $taxonomy, [ 'parent' => $parent ] );
// Prepare a new array. These are the children of $parent.
// We'll ultimately copy all the $terms into this new array, but only after they
// find their own children
$children = [];
// Go through all the direct descendants of $parent, and gather their children.
foreach ( $terms as $term ){
// Recurse to get the direct descendants of "this" term.
$term->children = get_taxonomy_hierarchy( $taxonomy, $term->term_id );
// Add the term to our new array.
$children[ $term->term_id ] = $term;
}
// Send the results back to the caller.
return $children;
}
/**
* Recursively get given taxonomies' terms as complete hierarchies.
*
* @param string|array $taxonomies Taxonomy slugs.
* @param int $parent - Starting parent term id
*
* @return array
*/
function get_taxonomy_hierarchy_multiple( $taxonomies, int $parent = 0 ) {
if ( ! is_array( $taxonomies ) ) {
$taxonomies = [ $taxonomies ];
}
$results = [];
foreach( $taxonomies as $taxonomy ){
$terms = get_taxonomy_hierarchy( $taxonomy, $parent );
if ( $terms ) {
$results[ $taxonomy ] = $terms;
}
}
return $results;
}
Usage:
$hierarchies = get_taxonomy_hierarchy_multiple( [ 'category', 'post_tag' ] );
// or for a single taxonomy
$hierarchy = get_taxonomy_hierarchy( 'category' );
What’s going on?
- During the first execution, we use
get_terms()
to gather all terms that do not have any parents ( parent = 0 ).
- Then, we loop through those terms and get each of their children by calling the
get_taxonomy_hierarchy()
on the terms.
- Every time we loop through a set of terms, we look for children that belong to each term.
- Finally, we return an array of terms with all it’s children stored within a new
$term->children
property.
Discussion
Nice, thanks.
Thanks mate!
Exactly what I need.
I get “Warning: Missing argument 1 for get_taxonomy_hierarchy()”
Sounds like you need to specify which taxonomy you’re trying to get. The core WordPress taxonomies are named “category” and “post_tag”.
Thanks, saved me a lot of time.
Nice work.
Thanks man, you saved me a lot of time and work :)
Works great, very succinct code. Thank you for sharing!
Great stuff, thank you! For those who want to return all taxonomies (even those without any posts), add `hide_empty` to the args passed. I also updated this example code to add the ability to pass an array of args as 3rd argument, to override the default ones, or add any specific ones, you can find at this gist:
https://gist.github.com/tripflex/631610f46350edf4b84d88dad75e6517
Thanks Jonathon, This saved the day for me :)
Jonathan, nice functions! This saved me a bunch of time. I hope things are going well on your side of Asheville.
Five years later and still the best solution I could stumble upon. I’m working on a variation that will allow me to pass a parent term and have it iterate only through that term’s children, I think you’ve set me up easily to do that. Thanks!
Hey, would you mind to share your code? Im looking for exactly that ;)