WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I have a Wordpress template with a single.php page. The page has "next" and "previous" arrows to allow navigating through all posts. I want to exclude posts from some categories from being included in the "next" and "previous" calculation. I have this code:

 // in single.php
 next_post_link( '%link', '← Previous', false, '11 and 13 and 15'); 

This should show the link to the next post. Posts in categories 11, 13, and 15 should not be considered as per the $ignore_categories parameter.

This works for posts that have only one of the categories listed set, e.g. 15. But posts that additionally have a non-excluded category (like 16 or 23), do not get excluded and they show up as the next post link.

Is this the intended behaviour? It doesn't seem to make sense to me.

Is there anything I can do to change it so a post gets excluded whenever it has one of the excluded categories, short of rebuilding the entire functionality?

share|improve this question
Can we have some code of what you are doing now? I'm struggling to get the picture here. – Brady Feb 10 '12 at 17:15
@Brady I edited to clarify. Let me know if it makes things clearer – Pekka 웃 Feb 10 '12 at 17:18
Much clearer thanks. I'm looking through the core code now, its looking messy this one might be over my head. – Brady Feb 10 '12 at 17:44

It makes perfect sense, but kind of backwards. I think the query that is executed to "exclude" posts from categories is grabbing all of the categories (this may return category IDs 1, 2, 5, 7, 11, 13, 15, 16, and 23) initially then checking the "exclude_category" param ("11 and 13 and 15") and running the query to grab all posts that BELONG in categories 1, 2, 5, 7, 16, and 23 (skipping over 11, 13, and 23). So technically the returned result is indeed correct.

So you can write a function similar to what i've pasted below:

function prev_next_dont_include( $ids ) {
foreach ( get_categories() as $category ) : // loop thru all WP cats
    if ( !in_array( $category->cat_ID, $ids ) ) : // check if cat id is in $ids
        $categories[] = $category->cat_ID; // build list of real excluded ids
return implode( ' and ', $categories ); // "1 and 2 and 5 and 7 and 16 and 23"

Now you can use that like this:

previous_post_link('%link',  __( '<span class="meta-nav">&larr;</span> Previous Article', 'twentyeleven' ), false, prev_next_dont_include( array( 11, 12, 15 ) ) );

Hopefully this will help someone out as it sure saved me.

share|improve this answer
This looks cool. Thanks, I will be testing this as soon as I can and get back to you! – Pekka 웃 Mar 3 '12 at 17:17
Note that there is a ) missing from Dwight Scott's answer, should be: previous_post_link('%link', __( '<span class="meta-nav">&larr;</span> Previous Article', 'twentyeleven' ), false, prev_next_dont_include( array( 11, 12, 15 ) ) ); – user51633 May 13 '14 at 15:48
Thanks! I've updated the code to reflect the missing closing paren. – Dwight Scott May 14 '14 at 16:34

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.