In WordPress it’s often desirable to restrict pagination to posts within the current posts’ category (or custom taxonomy); usually because of particular ordering requirements. For instance, when it wouldn’t make sense to mix posts of a certain category with others.

The easiest way to display next/previous post pagination on your single.php template (or single-custom-post-type.php template) is to use the next_post_link() and previous_post_link() functions. These both display the relevant posts adjacent to the current post.

But what if you want to paginate posts within the same category? Or, extending this further, within the same top level category.

How to Keep Post Pagination in Same Parent Category

By default WordPress will paginate between the first category the post is assigned to alphabetically. Probably not you’re after as navigating back and forth between posts will provide an inconsistent order.

The next_post_link() and previous_post_link() functions have built in parameters that we can make use of. First of all, to ensure the next and previous adjacent posts are within the same category (or taxonomy) we can set the $in_same_term option to TRUE:

Yet what if you want to paginate between posts within top level categories only? I came across this in a recent WordPress project using a custom post type (event) and custom taxonomies (event-category) to organise event data. The event category structure was as follows:

  • Top Level Event Category 1
    • Child Event Category 1
    • Child Event Category 2
    • Child Event Category  3
  • Top Level Event Category 2
    • Child Event Category 4
    • Child Event Category 5
    • Child Event Category 6

An event is exclusively categorised in one of the top level event categories and in up to three child event categories. Although $in_same_term is set to TRUE, the next_post_link() and previous_post_link() functions were linking to adjacent posts in any of the event categories the current event was in.

From the WordPress Codex on next_post_link():

If the post is in both the parent and subcategory, or more than one term, the next post link will lead to the next post in any of those terms.

Therefore not what we want when trying to retain a uniform order of events.

Exclude All Categories That Aren’t Top Level

The next_post_link() and previous_post_link() functions have another parameter that can be used together with $in_same_term$excluded_terms. This can be passed an array of, or string of comma-separated taxonomy term IDs to exclude.

This can be used to link to the next/previous post within the same category, unless that category is within the excluded categories.

In my case I used this to exclude any child level categories from my pagination, as I wanted to display events in order of either top level event category.

I wrote a custom function (in the theme’s functions.php file) that would return all term IDs of the current event post that aren’t top level:

To give me the required pagination order for the events in my single-event.php template, I could subsequently call my function here:

In Summary

Most of all it’s important to note that the above is a solution to a problem I encountered on a specific project. The code should be adapted to suit your needs. This will probably be straightforward and changing the taxonomy name should work for most cases.

You’ll also want to give the custom function a more appropriate name if you’re not dealing with events.

I hope this helps someone out!

Posted by Tom Hirst

Freelance WordPress developer, front-end developer and clothing line owner available for hire.

Leave a reply

Your email address will not be published. Required fields are marked *