Grouping WordPress Custom Loop Results
Posted by Pete Schuster on
All of my PHP knowledge comes from working with WordPress. The more and more I work with WordPress, and the further I push it, the more I need to rely on PHP to do some of the work. One common thing that I’ve run into in the past is grouping terms on a page. Whether its posts grouped by categories or a custom post type, grouped by a custom taxonomy, it comes up now and then. In the past, I’ve just created a multidimensional loop (which I know is bad), but it got the job done. Now that I’m a little more comfortable with PHP, however, I’ve figured out a way to accomplish this with only 2 calls to the DB. Below is an example of the code.
Step One: Get Your Group Terms
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | <?php //Builds Category Array $args = array( 'taxonomy' => 'ps_custom_tax', 'orderby' => 'title', 'order' => 'ASC' ); $cats_raw = get_categories( $args ); $cats = array(); foreach( $cats_raw as $cat_raw ) : $cats[ $cat_raw->term_id ] = array( 'cat_title' => $cat_raw->name, 'cat_slug' => $cat_raw->slug, 'cat_posts' => array() ); endforeach; ?> |
The function above builds a custom array of categories. Each category is an array of data about that category as well as an empty array of its posts.
Step Two: Fill in Your Posts
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | <?php //Main Query $args = array( 'post_type' => 'ps_custom_post_type', 'posts_per_page' => '-1' ); $the_query = new WP_Query( $args ); while ( $the_query->have_posts() ) : $the_query->the_post(); $post_cats = get_the_terms( $post->ID, 'ps_custom_tax' ); if ( is_array( $post_cats ) ){ foreach( $post_cats as $post_cat ) : $cats[ $post_cat->term_id ][ 'cat_posts' ][] = array( 'post_title' => get_the_title(), 'post_date' => get_the_date( 'F j, Y' ), 'post_content' => get_the_content(), 'post_link' => get_permalink() ); endforeach; } endwhile; wp_reset_postdata(); ?> |
The above function loops through each post, and fetches all the custom taxonomies it is associated with. If the post has any, it will add the post to the appropriate ‘posts’ array in the categories array.
Step Three: Profit
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | <ul> <?php //Main Output foreach( $cats as $cat ) : ?> <li id="<?php echo $cat[ 'cat_slug' ]; ?>" class="<?php echo $cat[ 'cat_slug' ]; ?>"> <h2><?php echo $cat[ 'cat_title' ]; ?></h2> <ul> <?php foreach( $cat[ 'cat_posts' ] as $cat_post ) : ?> <li> <h3><a href="<?php echo $cat_post[ 'post_link' ]; ?>"><?php echo $cat_post[ 'post_title' ]; ?></a></h3> <time><?php echo $cat_post[ 'post_date' ]; ?></time> <?php echo $cat_post[ 'post_content' ]; ?><br /> </li> <?php endforeach; ?> </ul> </li> <?php endforeach; ?> </ul> |
Now your original array is full of categories which are full of posts! Yippe! Let’s output them with the function above.
Conclusion
This method works really great and is a much better option to a multi-dimensional loop.