0

I have a site with several Custom Post Types: blog posts, movie reviews & book reviews. In my single.php template I call the_post_navigation().

When viewing a blog post the previous and next links only navigate to other posts of type blog, completely ignoring movies and books. If my previous post happens to be a book review, I want the previous link will take the user to that book review and not another blog post.

Same for when on a movie or book page. I don't want to limit previous and next to those post types. How can I accomplish this?

0

By default the the_post_navigation() uses the current post type, whatever it may be. Luckily, that function eventually calls get_adjacent_post() which has a few hooks we can use. The below uses get_{$adjacent}_post_where where $adjacent is either "previous" or "next":

/**
 * Modify the posts navigation WHERE clause
 * to include our acceptable post types
 * 
 * @param String $where - Generated WHERE SQL Clause
 * 
 * @return String
 */
function wpse375885_postnav_where( $where ) {
    
    global $wpdb, $post;
    
    // Return Early
    if( empty( $post ) ) {
        return $where;
    }
    
    $search = sprintf( "p.post_type = '%s'", $post->post_type );
    
    // Return Early - $where already modified
    if( false == strpos( $where, $search ) ) {
        return $where;
    }
    
    // Almost all non-builtin in post types
    $acceptable_post_types = array_merge(
        array( 
            'post',
            'page'
        ),
        get_post_types( array( 
            '_builtin' => false
        ) )
    );
    
    $placeholders   = array_fill( 0, count( $post_types ), '%s' );
    $format         = implode( ',', $placeholders );
    
    $replace = $wpdb->prepare( 
        "p.post_type IN ($format)",
        $post_types
    );
    
    return str_replace( $search, $replace, $where );
    
}
add_filter( 'get_next_post_where',      'wpse375885_postnav_where' );
add_filter( 'get_previous_post_where',  'wpse375885_postnav_where' );

Personally, I would replace $acceptable_post_types with an array of my known post types to prevent future installed plugins from being added to the list.
You could also change '_builtin' => true to truly bring in all post types.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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