I have a hierarchical custom taxonomy ("photos"), with 3 parent terms

  • color
  • location
  • year

Each parent term has several children terms. I have associated the "photos" taxonomy with pages and have tagged a bunch of pages with the relevant terms for each page.

For example, one page has terms:

  • red (child of "color")
  • sf (child of "location")
  • 2010 (child of "year")

What I would like to do is have some sort of conditional tag that displays the terms as such:

  • Color: Red
  • Location: SF
  • Year: 2010

Where the terms are linked.

I have tried to set up a conditional has_term but am blanking on how to echo the term from the array:

<strong>Color:</strong> <?php if( has_term( array( 'red', 'blue', 'green' ), 'photos' )  ) {
    // do something here

That code checks to see if any of the three terms ('red', 'blue', 'green') are associated with that page, and it works fine to test the term. I just do not know how to echo the active term.

I could always create taxonomies for each of what are now my parent level terms ("Color", "Location", and "Year"), but if there is another way to do it without separate taxonomies, that would be great.

Any suggestions would be very much appreciated.


I may suggest not combining each of these into hierarchical taxonomies, but setting up 3 distinct taxonomies. It seems like they are 3 unrelated properties of the photos, and thus, I would separate the code for them. Then you're not trying to code around nested taxonomy terms, but you can access them each individually. The taxonomies would be color, location and year.


Suppose your Color term has ID = 10. Replace "10" with your desired ID

$termID = 10;
$taxonomyname = "photos";
$termchildren = get_term_children( $termID, $taxonomyname );  

if (is_array($termchildren)){
echo "Color: ";
foreach ($termchildren as $child) {
    $term = get_term_by( 'id', $child, $taxonomyname );
    if (has_term($term->ID, $taxonomyname)){
       echo '<a href="' . get_term_link( $term->name, $taxonomyname ) . '">' . $term->name . '</a>';

Rinse and repeat for the other top taxonomies.

  • Thank you. I tried that and it returned ALL children for that parent term. I am looking for only the term that is associated with that particular page. There has to be a way but I can't figure it out. – Ethan Dec 14 '12 at 14:19
  • I have corrected the code to only display if has_term. Should work now – K Themes Dec 15 '12 at 11:52

The following code is not tested, but should works:

In functions.php put

function page_photos_terms($post_id = 0) {
   echo get_color_location_year($post_id, 'photos'); 

function get_color_location_year($post_id = 0, $taxonomy = 'photos') {
  if ( ! $post_id ) return '';
  $color = null;
  $location = null;
  $year = null;
  $out = array();
  $out_str = '';
  $ancestors = get_terms($taxonomy, array('parent' => 0) );
  if ( empty($ancestors) || is_wp_error($ancestors) ) return '';
  foreach ($ancestors as $ancestor ) {
    if ( $ancestor->slug == 'color') { $color = $ancestor; }
    if ( $ancestor->slug == 'location') { $location = $ancestor; }
    if ( $ancestor->slug == 'year') { $year = $ancestor; }
  $terms = get_the_terms( $post_id, $taxonomy );
  if ( empty($terms ) || is_wp_error($terms) ) return '';
  foreach ( $terms as $term ) {
    if ( $color && ($term->parent == $color->term_id) ) {
       $out['color'][] = $term->name;
    } elseif( $location && ($term->parent == $location->term_id) ) {
       $out['location'][] = $term->name;
    } elseif( $year && ($term->parent == $year->term_id ) ) {
       $out['year'][] = $term->name;
  foreach ( array('color', 'location', 'year') as $p ) {
    if ( ! empty($out[$p]) && is_object($$p) ) {
      $out_str .= sprintf('<li><strong>%s</strong>: ', $$p->name );
      $out_str .= implode(', ', $out[$p]) . '</li>';
  if ( $out_str != '' )  $out_str = '<ul class="photos-meta">' .  $out_str . '</ul>';
  return $out_str;

In page.php (or everywhere you need) put:

page_photos_terms( get_the_id() );

Function can be used with all post types that support photos taxonomy.

It works even outside the loop (passing a page/post id) and even if there are more than one color (or year, or location) on the page/post.

Hope it helps.


Try something like this in your PHP? I'm sure it can be optimized further.

$terms = get_the_terms($post_id, 'photos');//Get the 'photos' terms for just this page
if($terms) {
   //Loop through each term
   foreach( $terms as $term ) {
      //Check if the term has a parent
      if($term->parent != 0) {
         //Check if the parent term is one you want to include (color, location, and year)
         $parent = get_term($term->parent, 'photos');
         if($parent->slug == 'color' || $parent->slug == 'location' || $parent->slug == 'year') {
            //Echo out the parent's name followed by the term's name
            echo('<strong>'.$parent->name.':</strong> '.$term->name);

With this, you should be able to render any term that is assigned that has the color, location, or year as their parent. Especially helpful if you add or remove terms (like adding yellow), and now you won't have to update the code because it's checking for the parent's slug rather than the specific color.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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