Question

I've been using this piece of code for years on one of my websites:

            <?php
            if (is_category()) {
              $this_category = get_category($cat);
              if (get_category_children($this_category->cat_ID) != "") {
                echo "<ul class='subsubcats'>";
                    wp_list_categories('orderby=title&show_count=0&title_li=
                    &use_desc_for_title=1&child_of='.$this_category->cat_ID);
                echo "</ul>";
              } else {
                 get_template_part('loop'); // if no sub categories exist, show the posts
              }
            }
        ?> 

This shows all sub categories in a category overview page. And if there are no sub categories, it will show the containing posts.

I noticed with WP Debug that this code has actually been deprecated since WP 2.8, so it is high time to replace it.

I've read that I should replace this with get_terms. I've found a piece of code that almost does what I need:

            <?php

        $terms = get_terms([
            'taxonomy' => get_queried_object()->taxonomy,
            'parent'   => get_queried_object_id(),
        ]);

        echo '<ul class="subsubcats"><li class="categories"><ul>';
        foreach ( $terms as $term) {
            echo '<li class="cat-item"><a href="' . get_term_link( $term ) . '">' . $term->name . '</a></li>';  
        }
        echo "</ul></li></ul>";

        get_template_part('loop'); // if no sub categories exist, show the posts

        ?>

But there is one thing wrong with it: it shows the posts in all the category and sub category overviews, whereas the old code only shows the posts if there are no sub categories available.

I have no idea how to adjust this code to get it working the way I need, would really appreciate your help!

Was it helpful?

Solution

Yes, get_category_children() is indeed deprecated and you should use get_term_children() instead. So with your original code:

// You can simply replace this:
if (get_category_children($this_category->cat_ID) != "")

// with this:
$ids = get_term_children( $this_category->cat_ID, 'category' );
if ( ! empty( $ids ) )

And with your second code which uses get_terms(), you can check if the terms list is not empty and if it's not, display the terms; else, display the posts:

$terms = get_terms( ... );

if ( ! empty( $terms ) ) {
    // Display the terms.
    echo '<ul class="subsubcats"><li class="categories"><ul>';
    foreach ( $terms as $term ) {
        ... your code here ...
    }
    echo '</ul></li></ul>';
} else {
    // Display the posts.
    get_template_part( 'loop' );
}

But then, for what you're trying to do, it can actually be achieved with just wp_list_categories():

$list = wp_list_categories( array(
    'orderby'          => 'title',
    'title_li'         => '',
    'child_of'         => get_queried_object_id(), // just change the value if necessary
    'show_option_none' => '', // this does the trick
    'echo'             => 0,
) );

if ( ! empty( $list ) ) {
    echo '<ul class="subsubcats">' . $list . '</ul>';
} else {
    get_template_part( 'loop' );
}
Licensed under: CC-BY-SA with attribution
Not affiliated with wordpress.stackexchange
scroll top