Obtener publicaciones anteriores y siguientes por ID de publicación
¿Cómo puedo obtener las publicaciones anterior y siguiente desde fuera del bucle? Todo lo que intento hacer, aparte de la consulta SELECT personalizada (usando get_posts
o WP_Query
), rompe otras partes de la página.
Actualmente tengo una función recursiva que espera encontrar la primera publicación "anterior" que cumpla cierta condición. Obtengo el primer valor para probar desde get_previous_post()
pero no sé cómo obtener el previous_previous_post()
.
add_action( 'wp_ajax_nopriv_myajax-submit', 'ajax_project_load' );
add_action( 'wp_ajax_myajax-submit', 'ajax_project_load' );
function ajax_project_load() {
$the_slug = $_POST['slug'];
$args=array(
'name' => $the_slug,
'post_type' => 'projects',
'post_status' => 'publish',
'showposts' => 1,
'ignore_sticky_posts' => 1
);
$my_posts = get_posts($args);
if( $my_posts ) :
global $post;
$post = $my_posts[0];
$postCapabilityFilter = $_POST['capFilter']=='undefined' ? $_POST['capFilter'] : substr($_POST['capFilter'], 1);
$response = json_encode( "Success" );
header( "Content-Type: application/json" );
$next_post = get_previous_post();
function filtered_next_post($next_post){
if($next_post){
$next_slug = $next_post->post_name;
$next_ID = $next_post->ID;
global $wpdb;
global $postCapabilityFilter;
$querystr = "
SELECT $wpdb->postmeta.*
FROM $wpdb->posts, $wpdb->postmeta
WHERE $wpdb->posts.post_type = 'projects'
AND $wpdb->posts.post_status = 'publish'
AND $wpdb->posts.ID = $next_ID
AND $wpdb->posts.ID = $wpdb->postmeta.post_id
AND $wpdb->postmeta.meta_key = '_slideshow_content'
ORDER BY $wpdb->posts.post_name DESC
";
$nextProjQuery = $wpdb->get_results($querystr, OBJECT);
foreach($nextProjQuery as $nextProj):
$nextProjMetaArr = unserialize($nextProj->meta_value);
foreach ($nextProjMetaArr['slides'] as $npSlideArr){
echo 'y...';
if ( !in_array( $postCapabilityFilter, $npSlideArr['slideCap'] ) ){
echo 'no está en él...';
//$next_post = get_previous_previous_post();
//filtered_next_post($next_post);
}
}
endforeach;
return $next_slug;
}
}
$next_slug = filtered_next_post($next_post);

Echa un vistazo a get_previous_post()
y get_next_post()
y verás que ambas usan la función get_adjacent_post()
para encontrar el post anterior o siguiente.
Digamos que quieres obtener el ID del post inmediatamente anterior basado en el ID del post actual. Esto es lo que harías:
function get_previous_post_id( $post_id ) {
// Obtener una referencia global al post ya que get_adjacent_post() la requiere
global $post;
// Almacenar el objeto post existente para no perderlo
$oldGlobal = $post;
// Obtener el objeto post para el ID especificado y colocarlo en la variable global
$post = get_post( $post_id );
// Obtener el objeto post para el post anterior
$previous_post = get_previous_post();
// Restablecer nuestro objeto global
$post = $oldGlobal;
if ( '' == $previous_post ) {
return 0;
}
return $previous_post->ID;
}
Puedes hacer algo similar para obtener el ID del siguiente post... e incluso puedes hacer esto recursivamente si necesitas obtener el post anterior al anterior:
$post_hace_dos = get_previous_post_id( get_previous_post_id( $post->ID ) );
Resumen
Esencialmente, tanto get_previous_post()
como get_next_post()
hacen referencia a un objeto global $post
para realizar su selección. Necesitas configurar este objeto antes de llamar a cualquiera de estas funciones o no sabrán qué post usar como referencia para siguiente/anterior.
La función wrapper anterior simplemente configura el objeto global $post
por ti basándose en un ID pasado como parámetro. Podrías hacer que devuelva todo el objeto del post anterior en lugar del ID, eso depende completamente de ti.

Este es en realidad el enfoque con el que comencé, pero por alguna razón todo se bloqueaba cuando intentaba devolver $post
a $oldpost
. Sin errores, sin indicación de lo que estaba saliendo mal, solo un gif de carga girando. Probablemente algo raro con mi código, pero no podía entenderlo por nada del mundo. Ahora mi código está prácticamente funcionando, pero es una bestia de consultas SQL y me llevó varias horas armarlo.

Aquí puedes obtener el post adyacente para un tipo de post específico con una consulta SQL personalizada y con el filtro
get_{$adjacent}_post_where
donde el adyacente por defecto es el anterior. Además, el resultado depende de $current_post_date
y del operador de comparación $op
.
function bm_get_adjacent_post( $post_id, $author_id, $previous = 1 ) {
global $wpdb;
if ( ( ! $post = get_post( $post_id ) ) )
return null;
$current_post_date = $post->post_date;
$adjacent = $previous ? 'previous' : 'next';
$op = $previous ? '<' : '>';
$order = $previous ? 'DESC' : 'ASC';
$where = apply_filters( "get_{$adjacent}_post_where", $wpdb->prepare( "WHERE p.post_date $op %s AND p.post_type = %s AND p.post_status = 'publish' AND p.post_author = %d", $current_post_date, 'projects' , $author_id ), '', '' );
$sort = apply_filters( "get_{$adjacent}_post_sort", "ORDER BY p.post_date $order LIMIT 1" );
$query = "SELECT p.ID FROM $wpdb->posts AS p $where $sort";
//echo $query;
$result = $wpdb->get_var( $query );
if ( null === $result )
$result = '';
if ( $result )
$result = get_post( $result );
return $result;
}

Me encanta esta respuesta encontrada en: https://stackoverflow.com/a/33688032/2062851
function get_previous_post_id( $post_id ) {
// Obtener una referencia global al post ya que get_adjacent_post() la referencia
global $post;
// Almacenar el objeto post existente para no perderlo
$oldGlobal = $post;
// Obtener el objeto post para el ID especificado y colocarlo en la variable global
$post = get_post( $post_id );
// Obtener el objeto post para el post anterior
$previous_post = get_previous_post();
// Restablecer nuestro objeto global
$post = $oldGlobal;
if ( '' == $previous_post )
return 0;
return $previous_post->ID;
}
function get_next_post_id( $post_id ) {
// Obtener una referencia global al post ya que get_adjacent_post() la referencia
global $post;
// Almacenar el objeto post existente para no perderlo
$oldGlobal = $post;
// Obtener el objeto post para el ID especificado y colocarlo en la variable global
$post = get_post( $post_id );
// Obtener el objeto post para el siguiente post
$next_post = get_next_post();
// Restablecer nuestro objeto global
$post = $oldGlobal;
if ( '' == $next_post )
return 0;
return $next_post->ID;
}
entonces todo lo que tendrías que hacer es llamar a la función así:
echo get_previous_post_id( $current_id );
echo get_next_post_id( $current_id );
