Ottenere post precedenti e successivi tramite ID post
Come posso ottenere i post precedenti e successivi al di fuori del loop? Tutti i tentativi fatti, a parte una query SELECT personalizzata (usando get_posts
o WP_Query
), causano problemi nelle sezioni successive della pagina.
Attualmente ho una funzione ricorsiva che dovrebbe trovare il primo post "precedente" che soddisfa una determinata condizione. Prendo il primo valore da testare con get_previous_post()
ma non so come ottenere il 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 'e...';
if ( !in_array( $postCapabilityFilter, $npSlideArr['slideCap'] ) ){
echo 'non presente...';
//$next_post = get_previous_previous_post();
//filtered_next_post($next_post);
}
}
endforeach;
return $next_slug;
}
}
$next_slug = filtered_next_post($next_post);

Dai un'occhiata a get_previous_post()
e get_next_post()
e vedrai che entrambi utilizzano get_adjacent_post()
per trovare il post precedente o successivo.
Supponiamo che tu voglia recuperare l'ID del post immediatamente precedente basandoti sull'ID del post corrente. Ecco cosa dovresti fare:
function get_previous_post_id( $post_id ) {
// Ottieni un riferimento globale al post poiché get_adjacent_post() lo utilizza
global $post;
// Memorizza l'oggetto post esistente per dopo, così non lo perdiamo
$oldGlobal = $post;
// Ottieni l'oggetto post per l'ID specificato e inseriscilo nella variabile globale
$post = get_post( $post_id );
// Ottieni l'oggetto post per il post precedente
$previous_post = get_previous_post();
// Ripristina il nostro oggetto globale
$post = $oldGlobal;
if ( '' == $previous_post ) {
return 0;
}
return $previous_post->ID;
}
Puoi fare una cosa simile per recuperare l'ID del post successivo... e puoi farlo in modo ricorsivo se hai bisogno di ottenere il post precedente al precedente:
$two_posts_ago = get_previous_post_id( get_previous_post_id( $post->ID ) );
TL;DR
In sostanza, sia get_previous_post()
che get_next_post()
fanno riferimento a un oggetto globale $post
per effettuare la loro selezione. Devi impostare questo oggetto prima di chiamare entrambe le funzioni, altrimenti non sapranno quale post utilizzare come riferimento per il successivo/precedente.
La funzione wrapper sopra riportata semplicemente imposta il $post
globale per te basandosi su un ID passato. Potresti fargli restituire l'intero oggetto per il post precedente invece dell'ID, dipende interamente da te.

Questo è in realtà l'approccio con cui ho iniziato, ma per qualche motivo tutto si bloccava quando cercavo di restituire $post
a $oldpost
. Nessun errore, nessuna indicazione di cosa stesse andando storto, solo una gif di caricamento che girava all'infinito. Probabilmente qualcosa di strano nel mio codice, ma non riuscivo assolutamente a capire cosa fosse. Ora il mio codice funziona più o meno, ma è un mostro di query SQL e mi ci sono volute diverse ore per metterlo insieme.

Qui puoi ottenere il post adiacente per un tipo di post specifico con una query SQL personalizzata e con il filtro
get_{$adjacent}_post_where
dove il valore predefinito per adjacent è previous. Inoltre il risultato dipende da $current_post_date
e dall'operatore di confronto $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;
}

Amo questa risposta trovata su: https://stackoverflow.com/a/33688032/2062851
function get_previous_post_id( $post_id ) {
// Ottieni un riferimento globale al post poiché get_adjacent_post() lo utilizza
global $post;
// Memorizza l'oggetto post esistente per ripristinarlo successivamente
$oldGlobal = $post;
// Ottieni l'oggetto post per l'ID specificato e posizionalo nella variabile globale
$post = get_post( $post_id );
// Ottieni l'oggetto post per il post precedente
$previous_post = get_previous_post();
// Ripristina il nostro oggetto globale
$post = $oldGlobal;
if ( '' == $previous_post )
return 0;
return $previous_post->ID;
}
function get_next_post_id( $post_id ) {
// Ottieni un riferimento globale al post poiché get_adjacent_post() lo utilizza
global $post;
// Memorizza l'oggetto post esistente per ripristinarlo successivamente
$oldGlobal = $post;
// Ottieni l'oggetto post per l'ID specificato e posizionalo nella variabile globale
$post = get_post( $post_id );
// Ottieni l'oggetto post per il post successivo
$next_post = get_next_post();
// Ripristina il nostro oggetto globale
$post = $oldGlobal;
if ( '' == $next_post )
return 0;
return $next_post->ID;
}
quindi tutto ciò che devi fare è chiamare la funzione così:
echo get_previous_post_id( $current_id );
echo get_next_post_id( $current_id );
