0
votes

I have a parent category which has a lot of child categories, which also have a lot of their child categories and these categories have posts. I want to show on page all the child categories titles from the first parent category and posts titles only once. Now I have code which shows posts several times after every loop iteration, but I want to display it only once. Here is my code snippet

# get child categories
$sub_cats = get_categories( array(
    'child_of' => $parent_id,
    'hide_empty' => 0
) );
if( $sub_cats ){
    foreach( $sub_cats as $cat ){

        echo '<h3>'. $cat->name .'</h3>';

        # get posts from category
        $myposts = get_posts( array(
            'numberposts' => -1,
            'category'    => $cat->cat_ID,
            'orderby'     => 'post_date',
            'order'       => 'DESC',
        ) );
        # show posts
        global $post;
        foreach($myposts as $post){
            setup_postdata($post);
            echo '<li class = "test"><a href="'. get_permalink() .'">'. get_the_title() .'</a></li>';
        }
    }

    wp_reset_postdata(); 
}

I'm not WordPress developer, but I need to do this task. I didn't write this code, I just found it on the internet. Can someone help me to show posts only once or improve this code? thank you

1

1 Answers

0
votes

If you have duplicate post outputted:

  • It's certainly because post has multiple categories. So a single post will be found in multiple categories.
  • To prevent it, you could make a query for unique posts from your categories:

see:

//get terms from taxonomy category
$sub_cats = get_categories( [
    'child_of' => $parent_id,
    'hide_empty' => 0
] );

//wp-query post from your categories
$query    = new WP_Query( [ 'category__in' => array_map( function ( $o ) {
    return $o->term_id;
}, $sub_cats ) ] );

//only unique - never tested this
add_filter('posts_distinct', function(){return "DISTINCT";});

//your posts
$posts = $query->posts;

If you need to keep your loop as it is, you can use an array to store displayed post_ids and prevent duplicate to show:

# get child categories
$sub_cats = get_categories( array(
    'child_of' => $parent_id,
    'hide_empty' => 0
) );
$sub_cats_unique_posts = []; //array to store displayed post IDs

if( $sub_cats ){
    foreach( $sub_cats as $cat ){

        echo '<h3>'. $cat->name .'</h3>';

        # get posts from category
        $myposts = get_posts( array(
            'numberposts' => -1,
            'category'    => $cat->cat_ID,
            'orderby'     => 'post_date',
            'order'       => 'DESC',
        ) );
        # show posts
        global $post;
        foreach($myposts as $post){
            if(!in_array($post->ID, $sub_cats_unique_posts)){ //if not displayed already
                setup_postdata($post);
                echo '<li class = "test"><a href="'. get_permalink() .'">'. get_the_title() .'</a></li>';
                $sub_cats_unique_posts[] = $post->ID; //add this post ID to displayed one
            }
        }
    }

    wp_reset_postdata();
}

This should only display unique posts from $parent_id child categories.