Support » Developing with WordPress » Output latest posts from each child categories of particular parent category

  • I want to output latest post from each category (child category) that has parent. Parent category id is 54.

    For example, if there are 7 child categories under the category 54, the number of output post should be 7 (all latest from each child category). I hope this makes sense.

    My current code is below. At this stage, this code outputs only one latest post (of 1 child category) that has the latest under cat id=54. It would be great if you could advise me how to modify this so that I can get more latest post from multiple child categories.

    <?php 
    $categories = get_categories();
    foreach ( $categories as $category ) {
        $args = array(
        'cat' => 54,
        'post_type' => 'post',
        'posts_per_page' => '1',
        );
    }
    ?>
    <?php $query = new WP_Query( $args ); ?>
    <?php if ($query->have_posts()) : ?>
    <div class="container">
    
    <?php while ($query->have_posts()) : $query->the_post(); ?>   
    <div class="box">
    <article>
        <p><?php foreach((get_the_category()) as $childcat) { if (cat_is_ancestor_of(54, $childcat)) { echo '<a href="'.get_category_link($childcat->cat_ID).'">'; echo $childcat->cat_name . '</a>'; }} ?></p>
        <?php if ( has_post_thumbnail() ): ?><a href="<?php the_permalink(); ?>"><?php the_post_thumbnail('box-pic'); ?></a><?php endif; ?>
        <h3><a href="<?php the_permalink(); ?>"><?php the_title();?></a></h3>
    </article>
    </div>
    <?php endwhile;?>
    
    </div>
    <?php endif; ?>
    <?php wp_reset_query(); ?>
Viewing 6 replies - 1 through 6 (of 6 total)
  • Moderator bcworkz

    (@bcworkz)

    Get your child categories like so:
    $categories = get_categories(['parent' => 54,]);

    Then the ‘cat’ arg for the WP_Query args would be 'cat' => $category->term_id,

    Thanks bcworkz. I tried the code you suggested but the number of output was still 1..
    And strangely the output post this time was the second latest while my original code output the very latest post from all the child category.. I wonder why.

    There are more than 1 (currently 7) categories under the parent 54 and those child categories have their latest posts. It means that the number of output post should be 7.

    Moderator bcworkz

    (@bcworkz)

    Heh, it took me a while to see the problem. Look at what the category foreach loop encompasses. Just the $args assignment, nothing else! It needs to encompass everything. Move the closing curly brace from above the new WP_Query line to after the reset query line.

    BTW, wp_reset_query() is the wrong function in this context. Use wp_reset_postdata(). The reset query is for use with query_posts(). Reset postdata is for use with new WP_Query objects (and get_posts()). If your template will not need to make use of template tags like the_content(), the_title(), etc. as they relate to the original main query that returned the page your template is for, you don’t need to reset the post data because the original post data is not going to be used.

    However, I’ve noticed code many times that make use of post data when there is no reason to expect it to be valid, but they assume so all the same. So it’s good practice to reset post data anyway, needed or not.

    Your code works! I really appreciate your time looking into this. However now although all the output post is the latest from each child category (as planed), those post order is not ordered by date but by something else which I can confirm they are NOT by alphabetical order, ASC or DESC.. but I found it is the order shown in list of category edit view inside WordPress control panel. This is very strange..

    For example, I have a child cat A and B. If the child cat B has one post (post-X) with newer post-date than another (post-Y) from cat A. I want post-X to be on top of post-Y. Make sense?

    I have put 'orderby'=>'post_date', 'order'=>'DESC' and 'order'=>'modified' shown below but none of these works…

    <div class="carousel-wrap">
    <div class="carousel-container">
    <div class="slides">
    
    <?php 
    	$categories = get_categories(['parent' => 54,]);
    	foreach ( $categories as $category ) {
    		$args = array(
    		'cat' => $category->term_id,
    		'post_type' => 'post',
    		'posts_per_page' => '1',
    		'orderby' => 'modified'
    		);	
    	$query = new WP_Query( $args );
    ?>
    <?php if ($query->have_posts()) : ?>   
    <?php while ($query->have_posts()) : $query->the_post(); ?>   
    <div class="box">
    	<article>
    		<p><?php foreach((get_the_category()) as $childcat) { if (cat_is_ancestor_of(54, $childcat)) { echo '<a href="'.get_category_link($childcat->cat_ID).'">'; echo $childcat->cat_name . '</a>'; }} ?></p>
    		<?php if ( has_post_thumbnail() ): ?><a title="<?php the_title(); ?>" href="<?php the_permalink(); ?>"><?php the_post_thumbnail('box-pic'); ?></a><?php endif; ?>
    		<h3><a title="<?php the_title(); ?>" href="<?php the_permalink(); ?>"><?php the_title();?></a></h3>
    	</article>
    </div>
    <?php endwhile;?>
    <?php endif; ?>
    <?php wp_reset_postdata(); } ?>
    
    </div>
    </div>
    </div>

    This is the code now.
    Do you have any idea?

    These are posts from different queries. The orderby parameter sorts the results of one query. Maybe the easiest way to do it would be to collect the posts for each parent category in an array and then sort them manually (according to their date) before outputting them.

    Moderator bcworkz

    (@bcworkz)

    Yup, you got it, collect all the posts, then sort. You may need to use usort() to sort by the right field.

    I was about to suggest using the ‘category__in’ query argument to get all posts at once so SQL could do the sorting, but there’s no way with WP_Query to ensure exactly one post from each category. There may be a way with SQL alone, using $wpdb instead of WP_Query. I’m rather weak with SQL, but if anyone knows how this can be done, it would be superior to using PHP to do the same.

    All the same, sorting after the fact will work fine, even if it might not be the ideal way to do so.

Viewing 6 replies - 1 through 6 (of 6 total)
  • The topic ‘Output latest posts from each child categories of particular parent category’ is closed to new replies.