Filtra next_post_link () e previous_post_link () per meta_key?


8

Ho una pagina con due sezioni, ognuna ne usa una diversa WP_Query()da eventsinserire, che sono un tipo di post personalizzato. Ciascuno WP_Query()richiede a meta_keyper la data dell'evento in modo che la Sezione 1 visualizzi solo i prossimi eventse la Sezione 2 venga visualizzata events.

L'imminente eventsnella Sezione 1 mostra tutte le informazioni rilevanti sulla mia pagina, quindi non è possibile fare clic su di esse.

Il passato eventsnella Sezione 2 mostra solo il eventtitolo e sono cliccabili. Quando gli utenti fanno clic su un passato, eventsi collegano a un single-event.phpmodello personalizzato per il passato event.

Voglio visualizzare la navigazione precedente / successiva nel single-event.phpmodello, ma la navigazione dovrebbe puntare solo al passato events.

Ho provato a usare next_post_link()e previous_post_link()ma questi si collegheranno anche all'imminente events, che non voglio. Probabilmente posso installarne uno nuovo WP_Query()sul mio single-event.phpe scorrere attraverso di esso per ottenere gli ID Prev / Next, ma ripetere la query sembra un passo drastico.

Gradirei davvero alcuni approfondimenti su un modo per filtrare in uscita eventsdai miei link post precedente / successivo. Ho visto questa domanda ma preferirei non usare un plugin.


1
la risposta a questo è accennata nell'altra risposta alla domanda che hai collegato: dovrai filtrare le clausole join / where / sort nella get_adjacent_postfunzione.
Milo,

Sì, viene suggerito. Mi piacerebbe davvero vedere un esempio funzionante, se possibile.
cfr

1
Non ho tempo per programmare qualcosa al momento, ma un buon punto di partenza sarebbe quello di eseguire una query tramite WP_Query, quindi ispezionare $your_query_object->request, che rivelerà una buona parte dell'SQL che dovrai estrarre.
Milo,

Grazie per il suggerimento @Milo, penso di averlo capito! Vedi sotto!
Cfr

Risposte:


6

Sono riuscito a farlo funzionare utilizzando nient'altro che filtri WordPress, grazie al suggerimento di @ Milo.

Basta notare che questi sono piuttosto specifici per il mio caso, ma non dovresti avere problemi a modificarli per il tuo uso personale. Sto utilizzando i campi personalizzati avanzati con un campo Selettore data chiamato datee i collegamenti Prec / Succ. Indicano solo eventi con datecampi impostati su un giorno prima di oggi.

Ho creato 5 filtri:

  • 1 da modificare JOIN(da aggiungere wp_postmeta)
  • 1 da modificare WHEREper il collegamento precedente
  • 1 da modificare WHEREper il collegamento successivo
  • 1 da modificare SORTper il collegamento precedente
  • 1 da modificare SORTper il collegamento successivo

Ecco cosa mi è venuto in mente, sembra funzionare, ma se qualcuno individua dei problemi mi piacerebbe un feedback:

function get_adjacent_past_events_join($join) {
  if(is_singular('event')) {
    global $wpdb;
    $new_join = $join."INNER JOIN $wpdb->postmeta AS m ON p.ID = m.post_id ";
    return $new_join;
  }
  return $join;
}
add_filter('get_previous_post_join', 'get_adjacent_past_events_join');
add_filter('get_next_post_join', 'get_adjacent_past_events_join');

function get_prev_past_events_where($where) {
  if(is_singular('event')) {
    global $wpdb, $post;
    $id = $post->ID;
    $current_event_date = get_field('date', $id);
    $today = date('Ymd');
    $new_where = "WHERE p.post_type = 'event' AND p.post_status = 'publish' AND (m.meta_key = 'date' AND (m.meta_key = 'date' AND CAST(m.meta_value AS CHAR) < '$today')) AND (m.meta_key = 'date' AND (m.meta_key = 'date' AND CAST(m.meta_value AS CHAR) < '$current_event_date'))";
    return $new_where;
  }
  return $where;
}
add_filter('get_previous_post_where', 'get_prev_past_events_where');

function get_next_past_events_where($where) {
  if(is_singular('event')) {
    global $wpdb, $post;
    $id = $post->ID;
    $current_event_date = get_field('date', $id);
    $today = date('Ymd');
    $new_where = "WHERE p.post_type = 'event' AND p.post_status = 'publish' AND (m.meta_key = 'date' AND (m.meta_key = 'date' AND CAST(m.meta_value AS CHAR) < '$today')) AND (m.meta_key = 'date' AND (m.meta_key = 'date' AND CAST(m.meta_value AS CHAR) > '$current_event_date'))";
    return $new_where;
  }
  return $where;
}
add_filter('get_next_post_where', 'get_next_past_events_where');

function get_prev_past_events_sort($sort) {
  if(is_singular('event')) {
    global $wpdb;
    $new_sort = " GROUP BY p.ID ORDER BY m.meta_value+0 DESC";
    return $new_sort;
  }
  return $sort;
}
add_filter('get_previous_post_sort', 'get_prev_past_events_sort');

function get_next_past_events_sort($sort) {
  if(is_singular('event')) {
    global $wpdb;
    $new_sort = " GROUP BY p.ID ORDER BY m.meta_value+0 ASC";
    return $new_sort;
  }
  return $sort;
}
add_filter('get_next_post_sort', 'get_next_past_events_sort');

3

ho avuto un problema abbastanza simile, necessario per ordinare ed escludere diversi post dalla navigazione precedente / successiva. il problema con la soluzione di @ cfx era: non è in grado di ajax: la is_singular()funzione restituisce false se si carica il contenuto tramite wp-ajax. quindi ha funzionato al caricamento della pagina, ma non ha funzionato, quando il contenuto è stato modificato da Ajax. global $post;mi stava aiutando qui.

ecco la mia soluzione:

/**
  * WP: join postmeta to our sql query, so we can filter for custom fields
  *
  * @param $join
  * @return string
  */
function jnz_adjacent_work_join( $join ) {
  global $post;
  if ( get_post_type( $post ) == 'work' ) {
    global $wpdb;
    return $join . "INNER JOIN $wpdb->postmeta AS m ON p.ID = m.post_id ";
  }
  return $join;
}
add_filter('get_previous_post_join', 'jnz_adjacent_work_join');
add_filter('get_next_post_join', 'jnz_adjacent_work_join');



/**
 * WP: Change order of post for prev / next navigation
  * exclude posts with custom field "not_clickable" set to true
  *
  * @param $where
  * @param $operator
  * @return string|void
  */
 function jnz_adjacent_work_where( $where, $operator ) {
   global $post;
   if ( get_post_type( $post ) == 'work' ) :
     global $wpdb;
     $where = $wpdb->prepare("WHERE p.post_title {$operator} '%s' AND p.post_type = 'work' AND p.post_status = 'publish' AND (m.meta_key = 'not_clickable' AND (m.meta_key = 'not_clickable' AND m.meta_value != 1))", $post->post_title );
   endif;

   return $where;
 }

 $gt = '<';
 $lt = '>';
 add_filter( 'get_next_post_where', function( $where ) use ( $lt ) {
   return jnz_adjacent_work_where( $where, $lt );
 });
 add_filter( 'get_previous_post_where', function( $where ) use ( $gt ) {
   return jnz_adjacent_work_where( $where, $gt );
 });

in questo caso, la query del campo costum è: esclude tutti i post, che cf è not_clickableimpostato su true.

un altro problema che ho riscontrato: ho creato alcuni contenuti e successivamente ho implementato quel campo personalizzato .. quindi la query ha escluso anche i post che non avevano nemmeno quel campo allegato al post, non importa se vero o falso. tienilo a mente quando usi questo tipo di filtro. assicurati che ogni post abbia un valore o consideralo nella tua sintassi sql ..

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.