Skip Navigation

[Resolved] Links to next and previous sibling posts in a one-to-many post relationship

This thread is resolved. Here is a description of the problem and solution.

Problem: I have a one-to-many post relationship between two custom post types. In the template for the child post type, I would like to display "Next" and "Previous" links to paginate between the sibling posts.

Solution: Use a custom shortcode like this example that implements the post relationships API to create pagination links:

// https://toolset.com/forums/topic/next-and-previous-sibling-posts-in-a-one-to-many-post-relationship/
// 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' );

You'll 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>";
  }

Relevant Documentation:
https://toolset.com/documentation/customizing-sites-using-php/post-relationships-api/#toolset_get_related_post
https://toolset.com/documentation/customizing-sites-using-php/post-relationships-api/#toolset_get_related_posts

This support ticket is created 3 years, 10 months ago. There's a good chance that you are reading advice that it now obsolete.

This is the technical support forum for Toolset - a suite of plugins for developing WordPress sites without writing PHP.

Everyone can read this forum, but only Toolset clients can post in it. Toolset support works 6 days per week, 19 hours per day.

Sun Mon Tue Wed Thu Fri Sat
8:00 – 12:00 8:00 – 12:00 8:00 – 12:00 8:00 – 12:00 8:00 – 12:00 - -
13:00 – 17:00 13:00 – 17:00 13:00 – 17:00 13:00 – 17:00 13:00 – 17:00 - -

Supporter timezone: America/New_York (GMT-04:00)

This topic contains 3 replies, has 2 voices.

Last updated by alisonC 3 years, 10 months ago.

Assisted by: Christian Cox.

Author
Posts
#1933901

I would like to create next and previous links to sibling posts in a content template.

#1933939

Reference ticket using old relationships system: https://toolset.com/forums/topic/previous-next-within-parentchild-relationship/

Just a quick note to let you know I'm working on this per our initial discussion, and will try to convert that code to the new relationships systems/APIs.

#1934213

Okay I made some modifications based on the new post relationships API, and I put together an updated shortcode for you to use as an example:

// https://toolset.com/forums/topic/next-and-previous-sibling-posts-in-a-one-to-many-post-relationship/
// 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' );

You'll 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>";
  }

Depending on the sort order you expect for child posts, we may need to adjust the code a bit. It's currently sorted by child post title. Let me know what you think.

#1938199

This is brilliant, thank you Christian! The code is super-clear, and it will be easy to alter it according to my needs.