En WordPress previous_post_link() y next_post_link() permiten enlazar, en la plantilla de una entrada, la anterior y la siguiente entrada respectivamente. Estas entradas vienen definidas por unos parámetros por omisión que definen una petición a la base de datos que hace la función get_adjacent_post(). Estos parámetros definen que el criterio para seleccionar la entrada anterior y posterior sea la fecha de publicación.
Afortunadamente get_adjacent_post() dispone de tres hooks donde añadir filtros para modificar los parámetros de la petición a la base de datos para modificar las entradas previa y siguiente: get_{$adjacent}_post_join, get_{$adjacent}_post_sort y get_{$adjacent}_post_where. $adjacent puede tomar los valores previous y next.
Escribo a continuación el código necesario para cambiar el criterio para obtener la entrada previa y siguiente en base a un campo (custom field) numérico que haya servido para ordenar ascendentemente las entradas en la plantilla de archivo.
/**
* Join postmeta to the sql query, so we can filter for custom fields
*
* @param $join
*
* @return string
*/
function pfx_get_adjacent_post_join($join) {
if(is_singular('post')) {
global $wpdb;
$join = $join."INNER JOIN $wpdb->postmeta AS m ON p.ID = m.post_id";
}
return $join;
}
add_filter('get_previous_post_join', 'esfo_get_adjacent_cs_join');
add_filter('get_next_post_join', 'esfo_get_adjacent_cs_join');
/**
* Change where clause of post for prev / next navigation
*
* @param $where
*
* @return string|void
*/
function pfx_get_adjacent_cs_where($where, $operator) {
if(is_singular(ESFO_PT_CS)) {
global $wpdb, $post;
$pt = 'post';
$k = '_number';
$v = get_post_meta($post->ID,'_number',true);
$where = " WHERE p.post_type = '".$pt."' AND p.post_status = 'publish' AND ( m.meta_key = '".$k."' AND (m.meta_key = '".$k."' AND CAST(m.meta_value AS CHAR) $operator $v) )";
}
return $where;
}
add_filter( 'get_previous_post_where',
function( $where ) {
return pfx_get_adjacent_cs_where( $where, '<' );
}
);
add_filter('get_next_post_where',
function( $where ) {
return pfx_get_adjacent_cs_where( $where, '>' );
}
);
/**
* Change sort clause of post for prev navigation
*
* @param $sort
*
* @return string|void
*/
function pfx_get_prev_cs_sort($sort) {
if(is_singular('post')) {
global $wpdb;
$sort = " GROUP BY p.ID ORDER BY m.meta_value DESC LIMIT 1";
}
return $sort;
}
add_filter('get_previous_post_sort', 'pfx_get_prev_cs_sort');
/**
* Change sort clause of post for next navigation
*
* @param $sort
*
* @return string|void
*/
function pfx_get_next_cs_sort($sort) {
if(is_singular('post')) {
global $wpdb;
$sort = " GROUP BY p.ID ORDER BY m.meta_value ASC LIMIT 1";
}
return $sort;
}
add_filter('get_next_post_sort', 'pfx_get_next_cs_sort');
Si se quisiera usar otro criterio habrÃa que cambiar la petición a base de datos.
Encontré la pista para escribir este código en este hilo de stackexchange.