Wordpress - How To Create A Paginated List Of All Categories On My Site?

Paging a list of terms/categories/tags are quite easy, and to achieve that, you need minimal info.

Lets look at we need

  • the amount of terms

  • the amount of terms per page

  • get_terms() (Just note, the usage of get_terms() have changed in version 4.5). You can also use get_categories() if you wish, get_categories() is just a wrapper function for get_terms()

So first we need to count the amount of terms. For this, we will use the count parameter in get_terms()

NOTE:

  • All code is untested and requires at least

    • PHP 5.4

    • WordPress 4.5

You can easily convert this to work with older versions of PHP and WordPress

$taxonomy   = 'category';
$term_count = get_terms( 
    [
        'taxonomy'  => $taxonomy,
        'fields'    => 'count'
    ]
);

Now that we know the amount of terms, we can set the amount of terms we need per page, lets say 10

$terms_per_page = 10;

From the above, we can now work out how many pages we will have. The value here will be passed to the requires pagination function, in your case, to wp_pagenavi()

$max_num_pages = ceil( $term_count/$terms_per_page );

In this case, you would pass $max_num_pages to your pagination function

The next part would be to calculate our offset. We only want to retrieve the relevant amount of terms per page to keep things optimized. We do not need all 100+ terms per page. Querying only the needed 10 is much faster. So, we need to know on which page we are, are from that, we will calculate an offset. This will be passed to get_terms(), and will tell get_terms() how many terms to skip from the initial starting point.

Once have that, we must also tell get_terms() to only return 10 terms. Let look at the code for this piece

$current_page = get_query_var( 'paged', 1 ); // Change to 'page' for static front page
$offset       = ( $terms_per_page * $current_page ) - $terms_per_page;
$terms        = get_terms(
    [
        'taxonomy' => $taxonomy,
        'order'    => 'ASC',
        'orderby'  => 'name',
        'number'   => $terms_per_page,
        'offset'   => $offset
    ]
);

You will only have 10 terms per page according to pagination. You can now just loop normally through your terms

Just a note, you would want to make sure that you actually have terms returned from your get_terms() function.