I’ve got a custom post type called “products”, which has two custom taxonomies – “product-range” and “product-categories”. The range serves as a top-level grouping, whereas the category is a sub-grouping within that.
I’ve set-up a taxonomy-product-range.php template which features the following code:
<?php
$terms = get_terms('product-categories');
foreach( $terms as $term ):
?>
<h2><?php echo $term->name;?></h2>
<ul>
<?php
$posts = get_posts(array(
'post_type' => 'products',
'taxonomy' => $term->taxonomy,
'term' => $term->slug,
'nopaging' => true
));
foreach($posts as $post): setup_postdata($post);
?>
<li><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></li>
<?php endforeach; ?>
</ul>
<?php endforeach; ?>
This works as expected by outputting the products and grouping them by product category. However, it outputs all of the products, regardless of which archive you’re viewing. I need it to only output posts for the archive you’re viewing.
This feels like it’s nearly there, but I’m not sure how to fix it.
== Edit ==
Each of the products will belong to one “Range” and one “Category”. When people visit the product-range archive page, I’m trying to display the following:
<h1>Range Title</h1>
<h2>Category 1 Title</h2>
<ul>
<li>Product 1 Title</li>
<li>Product 2 Title</li>
<li>Product 3 Title</li>
</ul>
<h2>Category 2 Title</h2>
<ul>
<li>Product 4 Title</li>
<li>Product 5 Title</li>
<li>Product 6 Title</li>
</ul>
Simple remove the code that you have and replace it with the default loop. You should not replace the main query with a custom one. Use
pre_get_posts
to alter the main query according to needs.This is what your taxonomy page should look like
As your problem is sorting, we will tackle this using
usort
and theethe_posts
filter to do the sorting before the loop runs but just after the main query has run. We will not use multiple loops as they are quite expensive and resource intensive, and it breaks page functionalitiesI have commented the code so it can be easy to follow and understand. (NOTE: The following code is untested and requires PHP 5.4+ due to array dereferencing)
EDIT
Here is how your loop should look like to display your page in the order in your edit
EDIT 2
The code above is now tested and working. On request, here are the test run on my local install. For this test I have used the code in OP and my code.
RESULTS
(This results was obtained with the Query Monitor Plugin. Also, all results include the same extra queries made by widgets, nav menus, custom functions etc)
Code in OP -> 318 db queries in 0.7940 s with page generation time of 1.1670s. Memory usage was 12.8Mb
My code in answer -> 46 db queries in 0.1045 s with page generation time of 0.1305s. Memory usage was 12.6Mb
As I have stated previously, the proof is in the pudding