0

I have a hierarchical taxonomy filter that contains locations and genres for posts with the custom type artist:

- Genre
-- Hip Hop
-- Trap
-- Rap
- Location
-- Europe
--- Germany
--- Sweden
--- Austria
-- Asia
--- China
--- Japan
--- Taiwan

Now I would like to use get_terms() to only get the Countries (children of 'Location' without children of their own). I thought this should work:

$location_parent = get_term(123, 'filter');

$countries = get_terms(array(
  'taxonomy' => $location_parent->taxonomy,
  'hide_empty' => false,
  'child_of' => $location_parent->term_id, 
  'childless' => true
));

...but it somehow doesn't. child_of and childless seem to get in each other's way. Any ideas?

6
  • 2
    Are you sure having a single filter taxonomy is wise? A genre and location taxonomy would be better, looking at your hierarchy though, could you just tell it not to recurse down and ignore children? Or use more than one request? This is probably one of those situations were the real problem is that you're asking too much of 1 function call and you're in need of multiple steps
    – Tom J Nowell
    May 29, 2018 at 12:52
  • You are wrong with your thoughts: - Taxonomy is not "Location", Taxonomy is the name of your Custom Tax like category, post_tag, ... What's the name of your taxonomy? - What's is $location var?
    – IvanMunoz
    May 29, 2018 at 13:58
  • @TomJNowell, yes, usually that would be right. But in this particular case I can't use multiple taxonomies. Just expected childless and child_of to work together, don't you think?
    – rassoh
    May 29, 2018 at 20:05
  • @IvanMunoz The taxonomy is filter, not location. I will edit my question so this becomes clearer.
    – rassoh
    May 29, 2018 at 20:05
  • @TomJNowell can you explain a bit further what you mean by "just tell it not to recurse down and ignore children"?
    – rassoh
    May 29, 2018 at 20:12

2 Answers 2

2

OK, so this is what I came up with:

function get_childless_term_children( $parent_id, $taxonomy ) {
  // get all childless $terms of this $taxonomy
  $terms = get_terms(array(
    'taxonomy' => $taxonomy,
    'childless' => true,
  ));

  foreach( $terms as $key => $term ) {
    // remove $terms that aren't descendants (= children) of $parent_id
    if( !in_array( $parent_id, get_ancestors( $term->term_id, $taxonomy ) ) ) {
      unset( $terms[$key] );
    }
  }
  return $terms;
}

What this does: Get all childless terms that are children of $parent_id.

0

childless means:

(boolean) Returns terms that have no children if taxonomy is hierarchical, all terms if taxonomy is not hierarchical

Reference: https://codex.wordpress.org/es:Function_Reference/get_terms

I think you're finding something like this:

/**
 * Recursively get taxonomy hierarchy
 *
 * @source http://www.daggerhart.com/wordpress-get-taxonomy-hierarchy-including-children/
 * @param string $taxonomy
 * @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 decendents of the $parent
    $terms = get_terms( $taxonomy, array('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 = array();
    // go through all the direct decendents of $parent, and gather their children
    foreach( $terms as $term ) {
        // recurse to get the direct decendents 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;
}

It should return all the child from Location

We are agree?

1
  • This gives me all terms with their children. What I need is all terms that don't have children.
    – rassoh
    Jun 10, 2018 at 9:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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