Group list of posts by taxonomy and allow for pagination

The question:

There are multiple ways of showing a list of (custom) posts by taxonomy, but none appear to allow for pagination.

So, I can easily list all posts like:

Page 1

  • 1
  • 2
  • 3
  • 4
  • 5

Page 2

  • 6
  • 7
  • 8
  • 9
  • 10

With a little effort, I can list posts grouped by taxonomy

Page 1

  • A
    • 1
    • 2
  • B
    • 3
    • 4
    • 5
    • 6
  • C
    • 7
    • 8
  • D
    • 9
    • 10

But what I need help doing is mixing in pagination E.g.

Page 1

  • A
    • 1
    • 2
  • B
    • 3
    • 4
    • 5

Page 2

  • B
    • 6
  • C
    • 7
    • 8
  • D
    • 9
    • 10

Any ideas?

Example code below:

<?php
// Get current Category
$get_current_cat = get_term_by('name', single_cat_title('',false), 'category');
$current_cat = $get_current_cat->term_id;


// List posts by the terms for a custom taxonomy of any post type
$post_type = 'myposttype';
$tax = 'mytaxonomy';
$tax_terms = get_terms( $tax, 'orderby=name&order=ASC');
if ($tax_terms) {
    foreach ($tax_terms  as $tax_term) {
        $args = array(
            'post_type'         => $post_type,
            "$tax"              => $tax_term->slug,
            'post_status'       => 'publish',
            'posts_per_page'    => -1,
            'category__in'      => $current_cat // Only posts in current category (category.php)
        );

        $my_query = null;
        $my_query = new WP_Query($args);

        if( $my_query->have_posts() ) : ?>

            <h2><?php echo $tax_term->name; // Group name (taxonomy) ?></h2>

            <?php while ( $my_query->have_posts() ) : $my_query->the_post(); ?>
                <?php $term_list = wp_get_post_terms($post->ID, 'category', array("fields" => "ids")); // Get post categories IDs?>

                <?php if (in_array($current_cat, $term_list) ): // Display only posts that have current category ID ?>
                    <h3><?php the_title(); ?></h3>
                <?php endif; // if in_array ?>

            <?php endwhile; // end of loop ?>

        <?php endif; // if have_posts()
        wp_reset_query();

    } // end foreach #tax_terms
} // end if tax_terms

?>

The Solutions:

Below are the methods you can try. The first solution is probably the best. Try others if the first one doesn’t work. Senior developers aren’t just copying/pasting – they read the methods carefully & apply them wisely to each case.

Method 1

I figured it out!

First step, is to sort the posts by taxonomy (so that they’re grouped together).

This will give a list of posts that can be paginated (just like a regular list).

The trick now, is to add a (taxonomy) heading above related posts.

So, for each pass of the loop Im looking at the taxonomy in which the post belongs.
When this changes, I know that the “taxonomy group” has changed and therefore I need to show a heading.

E.g. Using my original example

  • 1 (Taxonomy A)
  • 2 (Taxonomy A)
  • 3 (Taxonomy B)
  • 4 (Taxonomy B)
  • 5 (Taxonomy B)
  • 6 (Taxonomy B)
  • 7 (Taxonomy C)
  • 8 (Taxonomy C)
  • 9 (Taxonomy D)
  • 10 (Taxonomy D)

For the first post, we don’t have a current taxonomy, so display a header

  • A
    • 1 (Taxonomy A)
    • 2 (Taxonomy A)

As we move from posts 2 to 3, the current taxonomy changes, so let’s display a header again

  • B
    • 3 (Taxonomy B)
    • 4 (Taxonomy B)
    • etc.

Here’s the code Im using

<?php if ( $the_query->have_posts() ) : ?>

  <ol>

  <?php $current_taxonomy = ''; while ( $the_query->have_posts() ) : $the_query->the_post(); ?>

  <?php
  $terms = get_the_terms( $post->ID, 'taxonomy_goes_here' );

  if ( $terms && ! is_wp_error( $terms ) ) : 

    $tax_terms = array();

    foreach ( $terms as $term ) {
      $tax_terms[] = $term->name;
    }

    $current_tax_terms = join( ", ", $tax_terms );
  ?>

  <?php endif; ?>

  <?php

    if($current_taxonomy != $current_tax_terms) {
      echo '<li><h2>'.$current_tax_terms.'</h2></li>';
      $current_taxonomy = $current_tax_terms;
    }

  ?>

  <li><?php the_title();?></li>

  <?php endwhile; ?>

  </ol>

<?php endif;?>


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Comment