[+] Display Next and Previous links to paginate between sibling posts in a one-to-many relationship

In this example, we have created a custom shortcode you can use to display pagination links like “Next: Next Sibling Post Title” and “Previous: Previous Sibling Post Title” to navigate among sibling child posts in a one-to-many post relationship. You can place this shortcode in the child post template to generate the appropriate link programmatically and display it only if necessary.

// get a link to the next or previous sibling post in child post content template
// example: [tssupp-next-prev-child current="[wpv-post-id]" step="1" relslug="book-chapter"][/tssupp-next-prev-child]
// @current: current post id
// @step: 1 for next or -1 for previous
// @relslug: slug of the post relationship
  
function tssupp_next_prev_child($atts) {
  $a = shortcode_atts( array(
    'current' => 0,
    'step' => '1',
    'relslug' => '',
  ), $atts );
  $link = '';
  
  // get all child posts
  $relationship_slug = $a['relslug'];
  $current_child_id = $a['current'];
  $parent_id = toolset_get_related_post( $current_child_id, $relationship_slug );
  $sibling_args = array(
    'query_by_role'=>'parent',
    'limit'=>1000,
    'role_to_return'=>'child',
    'orderby'=>'title'
  );
  $siblings = toolset_get_related_posts( $parent_id, $relationship_slug, $sibling_args );
  
  // loop over child posts and get index of the current post
  foreach($siblings as $i=>$sibling) {
    if( $sibling == $current_child_id ) {
      break;
    }
  }
  
  // increment or decrement index for next or previous sibling
  $i += $a['step'];
  
  // create link to next/previous sibling
  if(isset($siblings[$i])){
    $perm = get_the_permalink( $siblings[$i] );
    $title = get_the_title( $siblings[$i] );
    $link .= $a['step']=='1' ? "Next: " : "Previous: ";
    $link .= "<a href='" . $perm . "'>" . $title . "</a>";
  }
  
  // output the link, or empty string if not set
  return $link;
}
add_shortcode( 'tssupp-next-prev-child', 'tssupp_next_prev_child' );

Use the shortcode like this to generate a “Next” link (if necessary):

[tssupp-next-prev-child step="1" relslug="book-chapter" current="[wpv-post-id]"][/tssupp-next-prev-child]

Replace book-chapter with the slug of the post relationship.

You’ll change the step value to -1 to generate a “Previous” link (if necessary):

[tssupp-next-prev-child step="-1" relslug="book-chapter" current="[wpv-post-id]"][/tssupp-next-prev-child]

Again, replace book-chapter with the slug of the post relationship.

If you want to modify the links, you should only need to edit this part of the code:

// create link to next/previous sibling
  if(isset($siblings[$i])){
    $perm = get_the_permalink( $siblings[$i] );
    $title = get_the_title( $siblings[$i] );
    $link .= $a['step']=='1' ? "Next: " : "Previous: ";
    $link .= "<a href='" . $perm . "'>" . $title . "</a>";
  }

Get next post in the loop

Sometimes you need to access the next post in a loop, which is not created by Views, but when you are located on a Single Post.

For example, you want to display the Featured Image of the Post that comes next in the same Post Type, on the previous post.

The “next post” in the loop, can be accessed using the native WordPress function get_next_post()
https://codex.wordpress.org/Function_Reference/get_next_post

A ShortCode that returns the next post using this function can be crafted using these guidelines.
https://codex.wordpress.org/Shortcode_API

You should end up with:

function next_post_id( ) {
    $next_post_id = get_next_post()->ID;
    return $next_post_id;
}
add_shortcode( 'next-post-id', 'next_post_id' );

Now, you can use that in any ShortCode that supports an ID, in a single post, for example, to display the next’ posts’ image:

[wpv-post-featured-image item="[next_post_id]"]

Produce pretty pagination URL with Views

Yeah, our Views pagination URL is ugly.
It produces stuff like `example.com/type/?wpv_view_count=147-TCPID79&wpv_paged=2`

This is required for several features, as example AJAX pagination might not work if you do not use above URL format (which is native to Views)

What one can do is customize this a bit.
You need this Plugin:

WP-PageNavi

Then this code in your theme’s functions.php:

// Get the page number into wp_pagenavi
function pagenavi_paged($q) {
$types = (array)$q->get('post_type');
if (in_array('test', $types)) {
$paged = get_query_var('paged') ? get_query_var('paged') : 1;
$q->set('paged', $paged);
}

}
add_action('pre_get_posts', 'pagenavi_paged');

// create pagination shortcode
function custom_pagenavi($args, $content) {
global $WP_Views;
wp_pagenavi( array('query' => $WP_Views->post_query) );
}
add_shortcode('custom-pagination', 'custom_pagenavi');

If you do not restrict this on post types, then use this:

// Get the page number into wp_pagenavi
function pagenavi_paged($q) {

$paged = get_query_var('paged') ? get_query_var('paged') : 1;
$q->set('paged', $paged);

}
add_action('pre_get_posts', 'pagenavi_paged');

// create pagination shortcode
function custom_pagenavi($args, $content) {
global $WP_Views;
wp_pagenavi( array('query' => $WP_Views->post_query) );
}
add_shortcode('custom-pagination', 'custom_pagenavi');

Keep in mind that this is custom code that we cannot debug or provide in-depth explanations and customizations.