Previous or next in a custom post type archive.

I still like post types, i enjoy those types from the bottom of my heart. But this wordpress plays with me.

Just now i made a custom post archive for my calendar plugin. I just went directly to my custom post type page with my /calender url. Got a fantastic archive, or let me say post from the past for my archive. Lets start.

I want this article to be about the next and previous link in the item view. But if i forgot to mentioned the great pre_get_posts function in  the code. To view items from a custom post type in an archive use this:

add_action( 'pre_get_posts', 'dimme_calendar_post_type' );
function dimme_calendar_post_type( $query ) {
  if ( is_post_type_archive( 'calendar' ) && $query->is_main_query()) {
    if(is_admin()) {
      // no
    } else {
      $query->set( 'orderby', 'date' );
      $query->set( 'order', 'ASC' );
      $query->set( 'post_status', 'future,pending' );

  return $query;

Mind the is_admin() check. If you forget this you will find the admin page also only includes the future or pending status.

Now for the previous and next statements. I kindof hacked my way in these links. There is a previous_post_link or next_post_link post link filter i found useless. Wich i did find in the wp-includes/link-template.php file is the get_{$adjacent}_post_where statement. This is where the magic hapens. You only want to change the post_status in these functions so your query finds the next of previous item.

So the magic, add a filter for the previous or next post type:


In this filter change the post status check.

function my_custom_get_previous_post_where( $sql ) {
  if(get_post_type() == "calendar") { // dirty check for my post type
    $sql = str_replace("post_status = 'publish'", "post_status IN('publish','future','pending')", $sql); // even more dirty hack for the post status, muhaha
    return $sql;
  } else {
    return $sql;

In the original post status check in the post status check is more dirty and canot be changed with a function of maby a global $wpdb hack, it looks like this:

$where = apply_filters( "get_{$adjacent}_post_where", $wpdb->prepare("WHERE p.post_date $op %s AND p.post_type = %s AND p.post_status = 'publish' $posts_in_ex_cats_sql", $current_post_date, $post->post_type), $in_same_cat, $excluded_categories );

In link-template.php (wp 3.5.2 line 1174). You canot change the query variables in this.

So i just changed the status to an IN () array in the sql from the $sql you get from the original statment and only change the query and not create a new one for these hard hacks. There are also the get_{$adjacent}_post_join and get_{$adjacent}_post_sort if you want to change more. I just have not needed to change these settings for my plugin.

Now i found these settings, just need to update my plugin for the next release. Also have seeen a bug if you forgot to set the correct post type for the plugin, but that was a non issue when i updated my settings. So no need to mention this here.

Next, maby make a theme tutorial. But i planned that for some months now and haven`t started it yet.