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

Either this is harder than it needs to be or I am just not understanding WordPress/PHP very well 🙁 All I want to do is show the child/sub categories of a specific parent category…but only if the post is in those subcategories. Specific example:

I am building a wine reviews website and these are the categories:

  • Brand
    • Subcategory 1
    • Subcategory 2
    • etc.
  • Region
    • Subcategory 1
    • Subcategory 2
    • etc.
  • Grape
    • Subcategory 1
    • Subcategory 2
    • etc.

The parent categories will never change, and every post will have at least 1 subcategory selected under each parent, so in the LOOP I can just list the parents by name. But I am needing to dynamically output the subcategories, something like this:

Brand: <?php list_post_subcategories_of('brand'); ?>
Region: <?php list_post_subcategories_of('region'); ?>
Grape: <?php list_post_subcategories_of('grape'); ?>

Is there any easy way like this? It seems like this should be a basic function in WordPress? I’ve looked at the functions ‘get_categories’ and ‘in_category’ but they don’t seem to be able to do this.

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

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' ) . '" rel="nofollow noreferrer noopener">' . $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 ) . '" rel="nofollow noreferrer noopener" rel="nofollow noreferrer noopener">' . $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 ) . '" rel="nofollow noreferrer noopener">' . $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 ) . '" rel="nofollow noreferrer noopener" rel="nofollow noreferrer noopener">' . $category->name . '</a>';
        endif;
    endforeach;
    // join and output links with separator
    echo join( ', ', $links );
endforeach;


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x