skip to Main Content

I’m currently struggling with displaying custom taxonomy terms in a WordPress theme, and I can’t seem to get the desired output. I’m using a custom taxonomy called genre, which is attached to a custom post type. The problem is how I need to display the taxonomy terms on a single post page.

Desired Output:

I need to display parent categories with their subcategories in the following format:

Fiction (Cyberpunk, Timepunk (Steampunk/Paropunk)) | Fantasy (Heroic Fantasy)

The Problem:

At the moment, I’m using the following code in my functions.php file to generate the output:

function get_taxonomy_output($terms) {
    if (!is_wp_error($terms) && !empty($terms)) {
        $parent_cats = array();
        $child_cats = array();

        // Sort categories into parent and child categories
        foreach ($terms as $term) {
            if ($term->parent == 0) {  // This is the parent category
                $parent_cats[$term->term_id] = $term;
            } else {  // This is a child category
                $child_cats[$term->parent][] = $term;
            }
        }

        // Form the output line
        $output = array();
        foreach ($parent_cats as $parent_id => $parent_cat) {
            $output[] = build_category_output($parent_cat, $child_cats);
        }

        return implode(', ', $output);
    }
    return '';
}

function build_category_output($parent_cat, $child_cats) {
    $parent_link = '<a href="' . esc_url(get_term_link($parent_cat)) . '">' . esc_html($parent_cat->name) . '</a>';
    $output = $parent_link;

    if (!empty($child_cats[$parent_cat->term_id])) {
        $children = array();
        foreach ($child_cats[$parent_cat->term_id] as $child_cat) {
            // Check if the current subcategory has its own subcategories
            if (!empty($child_cats[$child_cat->term_id])) {
                $children[] = build_category_output($child_cat, $child_cats); // Recursively build child categories
            } else {
                $children[] = '<a href="' . esc_url(get_term_link($child_cat)) . '">' . esc_html($child_cat->name) . '</a>';
            }
        }
        $output .= ' (' . implode(', ', $children) . ')';
    }
    return $output;
}

And in single.php I have this code

$categories = get_the_terms(get_the_ID(), 'genre');
$output_genre = get_taxonomy_output($categories);

In the place where I want to display subcategories, this is displayed:

Fiction and Fantasy (Fiction (Cyberpunk, Timepunk (Steampunk/Paropunk), Fantasy (Heroic Fantasy)).

It should be like this:

Fiction (Cyberpunk, Timepunk (Steampunk/Paropunk) | Fantasy (Heroic Fantasy)

I attach an image of how it looks in the admin panel.

I am trying to make code that will be as optimized as possible and meet all WordPress development standards.

2

Answers


  1. It looks like there is a small issue with get_taxonomy_output function, so could you please try to replace given line of code in that function.

    return implode(', ', $output);
    

    with the given code.

    return implode(' | ', $output); // Here we are using ' | ' as the separator for parent categories.
    

    It should works for you.

    Login or Signup to reply.
  2. get_taxonomy_output Function:

    Uses implode(' | ', $output) to separate parent categories with |.

    build_category_output Function:

    Recursively builds the output for child categories and maintains proper formatting with parentheses.

    Updated Code:

    function get_taxonomy_output($terms) {
        if (!is_wp_error($terms) && !empty($terms)) {
            $parent_cats = array();
            $child_cats = array();
    
            // Sort categories into parent and child categories
            foreach ($terms as $term) {
                if ($term->parent == 0) {  // This is the parent category
                    $parent_cats[$term->term_id] = $term;
                } else {  // This is a child category
                    $child_cats[$term->parent][] = $term;
                }
            }
    
            // Form the output line
            $output = array();
            foreach ($parent_cats as $parent_id => $parent_cat) {
                $output[] = build_category_output($parent_cat, $child_cats);
            }
    
            // Return the output with a ' | ' delimiter
            return implode(' | ', $output);
        }
        return '';
    }
    
    function build_category_output($parent_cat, $child_cats) {
        $parent_link = '<a href="' . esc_url(get_term_link($parent_cat)) . '">' . esc_html($parent_cat->name) . '</a>';
        $output = $parent_link;
    
        if (!empty($child_cats[$parent_cat->term_id])) {
            $children = array();
            foreach ($child_cats[$parent_cat->term_id] as $child_cat) {
                // Check if the current subcategory has its own subcategories
                if (!empty($child_cats[$child_cat->term_id])) {
                    $children[] = build_category_output($child_cat, $child_cats); // Recursively build child categories
                } else {
                    $children[] = '<a href="' . esc_url(get_term_link($child_cat)) . '">' . esc_html($child_cat->name) . '</a>';
                }
            }
            $output .= ' (' . implode(', ', $children) . ')';
        }
        return $output;
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search