So it turns out that I didn’t do a loop of loops at all. This is several years old now. I don’t even know how I came up with that because clauses/limits and DB stuff are still a bit over my head. Anyway, I hope it helps some… I thought for sure I had a loop of loops, but that shouldn’t be all that hard to write either.
//remove limits from article CPT archive
function kia_archive_limits( $limits ) {
if( ! is_admin() && ( is_post_type_archive( 'article' ) ) ) {
// remove limits
$limits="";
}
return $limits;
}
add_filter('post_limits', 'kia_archive_limits' );
//complicated queries for articles depending on query var
function kia_article_clauses( $clauses, $wp_query ) {
global $wpdb;
if( is_post_type_archive( 'article' )) {
//join term_relationships to posts, and term_relationships to term_taxonomy and term_taxonomy to terms
$clauses['join'] .= "LEFT OUTER JOIN {$wpdb->term_relationships} ON {$wpdb->posts}.ID={$wpdb->term_relationships}.object_id
LEFT OUTER JOIN {$wpdb->term_taxonomy} USING (term_taxonomy_id)
LEFT OUTER JOIN {$wpdb->terms} USING (term_id)" ;
//group posts by term name
$clauses['groupby'] = "object_id";
//include posts with and without a subject term
$clauses['where'] .= " AND (taxonomy = 'subject' OR taxonomy IS NULL)";
$clauses['orderby'] = "GROUP_CONCAT({$wpdb->terms}.name ORDER BY name ASC) ";
}
return $clauses;
}
add_filter( 'posts_clauses', 'kia_article_clauses', 10, 2 );
And my loop code looked something like this:
<div class="column">
<?php
$prev = ''; $counter = 1; $column = 1;
while ( have_posts() ) : the_post();
$subhead = array_shift(wp_get_post_terms(get_the_ID(), 'subject', array("fields" => "names")));
$subhead = $subhead ? $subhead : __('No Subject','peterwade');
if($counter >= 20) {
//reset the counter
$counter = 1;
$column++;
//what column are we on?
if($column == 5 ){
$column = 1; //reset column count
$hr="<hr class="clear"/>";
} else {
$hr = false;
}
if ($column == 4) {
$class = "column last";
} else {
$class = "column";
}
?>
</div><!--.column-->
<?php if($hr) echo $hr;?>
<div class="<?php echo $class;?>">
<h3 class="subhead"><?php printf('%s <span class="continued">%s</span>', $subhead, __('continued'));?></h3>
<?php
}
if($subhead != $prev) {
$counter++; ?>
<h3 class="subhead"><?php echo $subhead;?></h3>
<ul>
<?php } ?>
<li><a href="https://wordpress.stackexchange.com/questions/136602/<?php echo get_permalink();?>" title="<?php echo __('Permalink to') . ' ' . get_the_title();?>"><?php the_title();?></a></li>
<?php
if($subhead != $prev) { ?>
</ul>
<?php }
$prev = $subhead;
$counter++;
endwhile; ?>
</div><!--.column-->
Now looking at the source on the page I linked you to, it would appear that he’s reverted to how he was doing things formerly…. aka… a giant table. Whether this was because my code stopped working I couldn’t say.
Alternative
This would be a loop of loops. Looping through the terms and then querying the posts in each term. You’d have to benchmark to determine which method is faster. I would highly suggested storing the queries in some kind of transient, but it is time for dinner!
$terms = get_terms( 'genre' );
if( $terms ):
foreach( $terms as $term ){
// The Query
$args = array(
'post_type' => 'book',
'nopaging' => true,
'tax_query' => array(
array(
'taxonomy' => 'genre',
'field' => 'id',
'terms' => $term->term_id
)
)
);
$the_query = new WP_Query( $args );
// The Loop
if ( $the_query->have_posts() ) {
echo '<h2>' . ucwords( $term->name ) . '</h2>';
echo '<ul>';
while ( $the_query->have_posts() ) {
$the_query->the_post();
echo '<li>' . get_the_title() . '</li>';
}
echo '</ul>';
}
}
endif;
/* Restore original Post Data */
wp_reset_postdata();