List only child categories a post is in, of a specific parent category

I would personally create three custom taxonomies rather than do this with categories/subcategories, then this becomes a non-issue.

To do this with categories/subcategories, start with the names/IDs of your parent categories, and loop over each parent, then within that, loop over the terms associated with the post and check the term’s parent ID against the top level category’s ID:

// names / IDs of parents
$parents = array(
    'Brand' => 42,
    'Region' => 22,
    'Grape' => 18
);
// get post categories
$categories = get_the_terms( $post->ID, 'category' );
// output top level cats and their children
foreach( $parents as $parent_name => $parent_id ):
    // output parent name and link
    echo '<a href="' . get_term_link( $parent_id, 'category' ) . '">' . $parent_name . '</a>: ';
    // initialize array to hold child links
    $links = array();
    foreach( $categories as $category ):
        if( $parent_id == $category->parent ):
            // put link in array
            $links[] = '<a href="' . get_term_link( $category ) . '">' . $category->name . '</a>';
        endif;
    endforeach;
    // join and output links with separator
    echo join( ', ', $links );
endforeach;

EDIT- dynamically fetch top level terms:

// get top level terms
$parents = get_terms( 'category', array( 'parent' => 0 ) );
// get post categories
$categories = get_the_terms( $post->ID, 'category' );
// output top level cats and their children
foreach( $parents as $parent ):
    // output parent name and link
    echo '<a href="' . get_term_link( $parent ) . '">' . $parent->name . '</a>: ';
    // initialize array to hold child links
    $links = array();
    foreach( $categories as $category ):
        if( $parent->term_id == $category->parent ):
            // put link in array
            $links[] = '<a href="' . get_term_link( $category ) . '">' . $category->name . '</a>';
        endif;
    endforeach;
    // join and output links with separator
    echo join( ', ', $links );
endforeach;

Leave a Comment