Restrict the post navigation to the same category

WordPress offers built-in functions to display the previous and next post link.

 

next_post_link( $format, $link, $in_same_term = false, $excluded_terms = '', $taxonomy = 'category' );

previous_post_link( $format, $link, $in_same_term = false, $excluded_terms = '', $taxonomy = 'category' );

As you can see there’s a boolean parameter named ‘in_same_term’.

This allows you to :

Indicates whether previous post must be within the same taxonomy term as the current post. If set to 'true', only posts from the current taxonomy term will be displayed. If the post is in both the parent and subcategory, or more than one term, the previous post link will lead to the previous post in any of those terms.

More documentation for those functions here.

Very handy !

 

But there are some cases when you need to go a bit further into coding. Typically, if you don’t want to modify a parent theme and rather customize it from a child theme.

 

Let’s say you have a theme with a custom display for your post navigation links, like the one used in the Customizr theme :

 

<ul class="pager">
                <?php if ( get_previous_post() != null ) : ?>
                  <li class="previous">
                    <span class="nav-previous">
                      <?php 
                        $singular_nav_previous_text   = apply_filters( 'tc_singular_nav_previous_text', _x( '&larr;' , 'Previous post link' , 'customizr' ) );
                        previous_post_link( '%link' , '<span class="meta-nav">' . $singular_nav_previous_text . '</span> %title' ); 
                      ?>
                    </span>
                  </li>
                <?php endif; ?>
                <?php if ( get_next_post() != null ) : ?>
                  <li class="next">
                    <span class="nav-next">
                      <?php
                        $singular_nav_next_text       = apply_filters( 'tc_singular_nav_next_text', _x( '&rarr;' , 'Next post link' , 'customizr' ) );
                        next_post_link( '%link' , '%title <span class="meta-nav">' . $singular_nav_next_text . '</span>' ); 
                        ?>
                    </span>
                  </li>
                <?php endif; ?>
              </ul>

In the above code, the in_same_term parameter is not set. To display the prev/next post link of the same category, we then have to filter the default behaviour or WordPress with the hooks API provided in wp-includes/link-template .

Note : Since Customizr 3.3.* (Customizr-Pro) two new filters have been added to simplify this process
add_filter('tc_previous_single_post_link_args', 'navigate_in_same_taxonomy');
add_filter('tc_next_single_post_link_args', 'navigate_in_same_taxonomy');
function navigate_in_same_taxonomy( $args ){
  $args['in_same_term'] = true;
  return $args;
}
Where to copy/paste this code?
Add it to your child-theme functions.php.
Everything you need to know about creating a child theme with Customizr here.
Note :  Following the old Code for Customizr 3.2.* and below

Here’s the code that will allow you to restrict the post navigation to the same category :

(Paste it in your functions.php)

add_filter( 'get_next_post_join', 'navigate_in_same_taxonomy_join', 20);
add_filter( 'get_previous_post_join', 'navigate_in_same_taxonomy_join', 20 );
function navigate_in_same_taxonomy_join() {
	global $wpdb;
	return " INNER JOIN $wpdb->term_relationships AS tr ON p.ID = tr.object_id INNER JOIN $wpdb->term_taxonomy tt ON tr.term_taxonomy_id = tt.term_taxonomy_id";
}


add_filter( 'get_next_post_where' , 'navigate_in_same_taxonomy_where' );
add_filter( 'get_previous_post_where' , 'navigate_in_same_taxonomy_where' );
function navigate_in_same_taxonomy_where( $original ) {
	global $wpdb, $post;
	$where 		= '';
	$taxonomy  	= 'category';
	$op 		= ('get_previous_post_where' == current_filter()) ? '<' : '>';
	$where 		= $wpdb->prepare( "AND tt.taxonomy = %s", $taxonomy );
	if ( ! is_object_in_taxonomy( $post->post_type, $taxonomy ) )
		return $original ;

	$term_array = wp_get_object_terms( $post->ID, $taxonomy, array( 'fields' => 'ids' ) );

	$term_array = array_map( 'intval', $term_array );

	if ( ! $term_array || is_wp_error( $term_array ) )
		return $original ;

	$where 		= " AND tt.term_id IN (" . implode( ',', $term_array ) . ")";
	return $wpdb->prepare( "WHERE p.post_date $op %s AND p.post_type = %s AND p.post_status = 'publish' $where", $post->post_date, $post->post_type );
}

 

14 thoughts on “Restrict the post navigation to the same category”

Comments are closed.