4

I need to find a way to list all categories - empty or not - in a hierarchial list - like wp_list_categories - also showing the slug, cat name and a link to edit in the admin.

Here is what I have so far:

$args = array(
        'orderby'   => 'name',
        'order'     => 'ASC',
        'hide_empty'    => '0',
  );

$categories = get_categories($args);

foreach( $categories as $category ) { 

    $cat_ID = $category->term_id;
    $cat_name = $category->name;
    #$cat_desc = $category->description; if ( !$cat_desc { $cat_desc = 'Nada!' } );
    $cat_count = $category->count;

    echo '<p><strong>'.$cat_name.'</strong>';
    echo ' / <a href="' . get_category_link( $cat_ID ) . '" title="' . sprintf( __( "View all posts in %s" ), $cat_name ) . '" ' . '>View ( '. $cat_count . ' posts )</a>  ';
    #echo ' / Desc: '. $cat_desc . '';
    echo ' / <a href="'. get_admin_url().'edit-tags.php?action=edit&taxonomy=category&tag_ID='.$cat_ID.'&post_type=post" title="Edit Category">Edit</a>';
    echo '</p>';  

}

All is good, but not nicely ordered - just an alphabetical list.

10

output as unordered list:

<?php

    hierarchical_category_tree( 0 ); // the function call; 0 for all categories; or cat ID  

function hierarchical_category_tree( $cat ) {
    // wpse-41548 // alchymyth // a hierarchical list of all categories //

  $next = get_categories('hide_empty=false&orderby=name&order=ASC&parent=' . $cat);

  if( $next ) :    
    foreach( $next as $cat ) :
    echo '<ul><li><strong>' . $cat->name . '</strong>';
    echo ' / <a href="' . get_category_link( $cat->term_id ) . '" title="' . sprintf( __( "View all posts in %s" ), $cat->name ) . '" ' . '>View ( '. $cat->count . ' posts )</a>  '; 
    echo ' / <a href="'. get_admin_url().'edit-tags.php?action=edit&taxonomy=category&tag_ID='.$cat->term_id.'&post_type=post" title="Edit Category">Edit</a>'; 
    hierarchical_category_tree( $cat->term_id );
    endforeach;    
  endif;

  echo '</li></ul>'; echo "\n";
}  
?>
  • genius! - hide_empty seems to require a numeric value to work, the rest is spot on - thanks! – Q Studio Feb 8 '12 at 21:31
  • perhaps unrelated to my original question, but how could I determine the "level" of the category hierarchy each category is on - for example in a 3 level hierarchy, I'd need to get 1, 2 or 3? – Q Studio Feb 8 '12 at 22:03
  • pastebin.com/GbZFnytw - depth output added as css class of ul tag – Michael Feb 8 '12 at 22:24
  • amazing - is there any way to nest the ul / li's - so that they all wrap around - I'd like to try and get them into an accordion type open / close navigation? – Q Studio Feb 9 '12 at 22:50
  • by nesting I meant <ul><li><ul><li></li></ul></li></ul> - I guess you figured that... – Q Studio Feb 10 '12 at 9:00
2

A slightly updated version of Michael’s answer to use the more generic get_terms (so you can get custom taxonomies, in this case I wanted the WooCommerce product category taxonomy of product_cat).

echo hierarchical_term_tree();

function hierarchical_term_tree($category = 0)
{
    $r = '';

    $args = array(
        'parent' => $category,
    );

    $next = get_terms('product_cat', $args);

    if ($next) {
        $r .= '<ul>';

        foreach ($next as $cat) {
            $r .= '<li><a href="' . get_term_link($cat->slug, $cat->taxonomy) . '" title="' . sprintf(__("View all products in %s"), $cat->name) . '" ' . '>' . $cat->name . ' (' . $cat->count . ')' . '</a>';
            $r .= $cat->term_id !== 0 ? hierarchical_term_tree($cat->term_id) : null;
        }
        $r .= '</li>';

        $r .= '</ul>';
    }

    return $r;
}

Simplified a little to take out the edit link etc. You can add those as required.

  • Error : PHP Catchable fatal error: Object of class WP_Error could not be converted to string. On this line : foreach ($next as $cat) . – Mehdi Dec 14 '18 at 2:08
  • This looks nice. How could I modify it to actually show the starting term at the top of the list? Currently, it shows all of the child terms, right? I'm using a non-0 term ID, ie. a valid term ID, not just all of them. – Robert Andrews Feb 2 at 10:25
0

You can use following code:

$args = array(

    'hide_empty'         => 0,
    'echo'               => 1,
    'taxonomy'           => 'category',
    'hierarchical'  =>1,
    'show_count' => 1,

);

function add_class_wp_list_categories($wp_list_categories) {
        $pattern = '/<li class="/is';
        $replacement = '<li class="first ';
        return preg_replace($pattern, $replacement, $wp_list_categories);
}
add_filter('wp_list_categories','add_class_wp_list_categories');

echo wp_list_categories( $args );
New contributor
Mahdi Afzal is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct.
-1

Hmm I think you need to include 'hierarchical' => 1, in your args list. Also you have one comma too much at the end of the args list. After the last argument you do not need a comma :)

Here's a complete example:

$args = array(
        'orderby'   => 'name', 
        'order'     => 'ASC', 
        'hierarchical' => 1,
        'hide_empty'    => '0'
  );

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.