0

Im looking for a way to loop through categories and then display the recent posts for each one in a container but I need a way to sort the categories by which ones have the most recent posts

So if Category C has a more recent post then it'll appear first before Category A

        $args = array(
           'hide_empty'=> 1
        );
        $categories = get_categories($args);
        foreach($categories as $category) { 
                    $the_query = new WP_Query(array(
                        'post_type' => 'article',
                        'posts_per_page' => 100,
                        'category_name' => $category->slug
                    ));

                    while ( $the_query->have_posts() ) : 
                    $the_query->the_post(); ?>
                       // post studd
                    endwhile;
        }

1 Answer 1

1

First set a function to be used later with a usort to sort the categories by date of most recent post:

    function orderByDate( $a, $b ) {
        return strtotime($a['date']) - strtotime($b['date']);
    }

Get your categories as you were doing:

    $args = array(
       'hide_empty'=> 1
    );
    $categories = get_categories($args);
    $categoriesWithDates = array(); // Create an array variable to be used in a moment
    $counter = 0;
    foreach($categories as $category) { 
        $the_query = new WP_Query(array(
            'post_type' => 'article',
            'posts_per_page' => 1, //This time only get one post
            'category_name' => $category->slug,
            'order' => 'DESC'
        ));

In the while loop, we create an array containing the category slug and the date of it's most recent post:

        while ( $the_query->have_posts() ) : 
            $the_query->the_post();
            $categoriesWithDates[$counter] = array('slug' => $category->slug, 'date' => get_the_date(DATE_RFC2822));
        endwhile;
      $counter++;
    }
    wp_reset_query();

Sort the categories by date using usort and the function orderByDate()

    usort($categoriesWithDates, "orderByDate");

Create a new loop to display the posts, this time using the newly created and date sorted array, categories with dates. This will have ordered your category slugs in order of which has the most recent posts, putting this into your query with a foreach will therefore display the categories in the order you want them to be:

    foreach($categoriesWithDates as $categoryWithDate) { 
                $the_query = new WP_Query(array(
                    'post_type' => 'article',
                    'posts_per_page' => 100,
                    'category_name' => $categoryWithDate['slug']
                ));

                while ( $the_query->have_posts() ) : 
                $the_query->the_post();
                  // Post studd 
                endwhile;
    }

There might be a better way to craft this all into one loop, but it would take more thinking, and this should get you started anyway! Something like this should do the trick, though I've not tested it.

EDIT:

I've added in a counter which I think might help resolve the issues. Also, I've set the date format on get_the_date() to DATE_RFC2822 (See: http://php.net/manual/en/function.date.php). Also, wp_reset_query(); has been added between the two queries.

7
  • I'm getting two errors... Illegal string offset 'date' for the first function. And then "Illegal string offset 'slug' "
    – user300979
    Commented Apr 9, 2016 at 0:47
  • What are the errors that you're getting?
    – Adam
    Commented Apr 9, 2016 at 0:49
  • Sorry I edited. Accidently hit enter before posting them
    – user300979
    Commented Apr 9, 2016 at 0:49
  • No problem, I've added some edits to my question, I think it might be the index of the arrays not being set properly.
    – Adam
    Commented Apr 9, 2016 at 0:58
  • I have to add a semicolon after get_the_date() or I can get an error. After doing that the loop is only showing one category which aslo contains the oldest posts
    – user300979
    Commented Apr 9, 2016 at 1:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.