Pregunta

I'm exhaustively searching for a method to provide Next and Previous Post Links in a different way from which it usually appears in Single Post.

By DEFAULT it:

  • Is chronological ordered

  • Links to posts from all blog categories

But I NEED it:

  • ALPHABETICALLY ordered

  • Linking to posts on SAME CATEGORY only

I'm not a developer but I think if I could merge the two codes below the problem would be solved.

CODE 1 - Turn Next/Prev links alphabetcally, but not from same category (source)

function filter_next_post_sort($sort) {
    $sort = "ORDER BY p.post_title ASC LIMIT 1";
    return $sort;
}
function filter_next_post_where($where) {
    global $post, $wpdb;
    return $wpdb->prepare("WHERE p.post_title > '%s' AND p.post_type = '". get_post_type($post)."' AND p.post_status = 'publish'",$post->post_title);
}

function filter_previous_post_sort($sort) {
    $sort = "ORDER BY p.post_title DESC LIMIT 1";
    return $sort;
}
function filter_previous_post_where($where) {
    global $post, $wpdb;
    return $wpdb->prepare("WHERE p.post_title < '%s' AND p.post_type = '". get_post_type($post)."' AND p.post_status = 'publish'",$post->post_title);
}

add_filter('get_next_post_sort',   'filter_next_post_sort');
add_filter('get_next_post_where',  'filter_next_post_where');

add_filter('get_previous_post_sort',  'filter_previous_post_sort');
add_filter('get_previous_post_where', 'filter_previous_post_where');

CODE 2 - Turn Next/Prev links from same category, but not alphabetically (source)

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 );
}

THANK YOU FOR HELP ME!

¿Fue útil?

Solución

To get next/prev posts, usually all you need is to se to true the parameter that indicates that next/prev post should be in the same taxonomy term in the get next/prev post functions, you don't need to deal with any filter.

For example:

To get next and prev post objects:

// First parameter for these functions indicates
// if next/prev post should be in the same taxonomy term
// More in https://codex.wordpress.org/Function_Reference/get_next_post
// And https://codex.wordpress.org/Function_Reference/get_previous_post
$prev_post = get_previous_post(true);
$next_post = get_next_post(true);

To print prev/next post links:

// Third parameter for these functions indicates
// if next/prev post should be in the same taxonomy term
// More in https://codex.wordpress.org/Template_Tags/next_post_link
// And https://codex.wordpress.org/Template_Tags/previous_post_link
previous_post_link( '&laquo; %link', '%title', true );
next_post_link( '%link &raquo;', '%title', true );

The problem is that, when you filter the where statement to change the order, you change the same taxonomy part, so you need to rebuilt it.

This code should work (I've not tested it):

add_filter('get_next_post_sort',  'filter_next_and_prev_post_sort');
add_filter('get_previous_post_sort',  'filter_next_and_prev_post_sort');
function filter_next_and_prev_post_sort($sort) {
    $op = ('get_previous_post_sort' == current_filter()) ? 'DESC' : 'ASC';
    $sort = "ORDER BY p.post_title ".$op ." LIMIT 1";
    return $sort;

}

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' , 'filter_next_and_prev_post_where' );
add_filter( 'get_previous_post_where' , 'filter_next_and_prev_post_where' );
function filter_next_and_prev_post_where( $original ) {
  global $wpdb, $post;
  $where = '';
  $taxonomy   = 'category';
  $op = ('get_previous_post_where' == current_filter()) ? '<' : '>';

  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_title $op %s AND p.post_type = %s AND p.post_status = 'publish' $where", $post->post_title, $post->post_type );
}

Otros consejos

Adapted for custom post type category worked flawlessly.

My question is to run this filter only on certain pages. how can i add one.

add if (! is_singular ('portfolio'))

add_filter( 'get_next_post_join', 'results_navigate_in_same_taxonomy_join', 20);
add_filter( 'get_previous_post_join', 'results_navigate_in_same_taxonomy_join', 20 );
function results_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' , 'results_navigate_in_same_taxonomy_where' );
add_filter( 'get_previous_post_where' , 'results_navigate_in_same_taxonomy_where' );
function results_navigate_in_same_taxonomy_where( $original ) {
    global $wpdb, $post;
    $where      = '';
    $taxonomy   = 'portfolio_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 );
}
Licenciado bajo: CC-BY-SA con atribución
scroll top