Saring next_post_link () dan prior_post_link () oleh meta_key?

8

Saya memiliki halaman dengan dua bagian, masing-masing menggunakan yang berbeda WP_Query()untuk menarik events, yang merupakan jenis posting kustom. Setiap WP_Query()pertanyaan meta_keyuntuk tanggal acara sehingga Bagian 1 hanya menampilkan mendatang eventsdan Bagian 2 menampilkan masa lalu events.

eventsBagian 1 yang akan datang menampilkan semua informasi yang relevan di halaman saya, jadi mengkliknya tidak mungkin.

Masa lalu eventsdi Bagian 2 hanya menampilkan eventjudul dan dapat diklik. Saat pengguna mengeklik masa lalu, eventmereka menautkan ke single-event.phptemplat khusus untuk masa lalu event.

Saya ingin menampilkan navigasi Sebelumnya / Berikutnya dalam single-event.phptemplate, tetapi navigasi seharusnya hanya menunjukkan masa lalu events.

Saya mencoba menggunakan next_post_link()dan previous_post_link()tetapi ini akan menghubungkan ke mendatang eventsjuga, yang saya tidak mau. Saya mungkin dapat mengatur yang baru WP_Query()pada saya single-event.phpdan mengulanginya untuk mendapatkan ID Sebelumnya / Berikutnya, tetapi mengulangi kueri sepertinya langkah yang drastis.

Saya akan sangat menghargai beberapa wawasan tentang cara untuk menyaring keluar eventsdari tautan posting Sebelumnya / Berikutnya saya. Saya telah melihat pertanyaan ini, tetapi saya lebih suka tidak menggunakan plugin.

cfx
sumber
1
jawaban untuk ini diisyaratkan di jawaban lain untuk pertanyaan yang Anda tautkan - Anda harus memfilter klausa join / where / sort dalam get_adjacent_postfungsi.
Milo
Ya itu mengisyaratkan. Saya benar-benar ingin melihat contoh kerja jika memungkinkan.
cfx
1
Saya tidak punya waktu untuk kode sesuatu saat ini, tetapi titik awal yang baik adalah melakukan query via WP_Query, kemudian memeriksa $your_query_object->request, yang akan mengungkapkan sedikit SQL yang Anda butuhkan untuk melakukannya.
Milo
Terima kasih atas petunjuknya @Milo, pikir saya sudah menemukan jawabannya! Lihat di bawah!
cfx

Jawaban:

6

Saya berhasil membuatnya berfungsi hanya dengan menggunakan filter WordPress, berkat petunjuk @ Milo.

Harap perhatikan bahwa ini cukup spesifik untuk kasus saya, tetapi Anda seharusnya tidak memiliki masalah memodifikasinya untuk Anda gunakan sendiri. Saya menggunakan Bidang Kustom Tingkat Lanjut dengan bidang Pemilih Tanggal yang dipanggil datedan tautan Sebelumnya / Berikutnya hanya menunjuk ke acara dengan datebidang yang disetel ke hari apa pun sebelum hari ini.

Saya membuat 5 filter:

  • 1 untuk memodifikasi JOIN(menambah wp_postmeta)
  • 1 untuk memodifikasi WHEREuntuk tautan Sebelumnya
  • 1 untuk memodifikasi WHEREuntuk tautan Berikutnya
  • 1 untuk memodifikasi SORTuntuk tautan Sebelumnya
  • 1 untuk memodifikasi SORTuntuk tautan Berikutnya

Inilah yang saya buat, tampaknya berhasil tetapi jika ada yang melihat masalah apa pun, saya akan sangat menyukai umpan balik:

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');
cfx
sumber
3

Saya punya masalah yang hampir sama, perlu menyortir dan mengecualikan beberapa posting dari navigasi prev / next. masalah dengan solusi @ cfx adalah: tidak mampu untuk ajax: is_singular()fungsi mengembalikan false, jika Anda memuat konten melalui wp-ajax. jadi itu berfungsi pada pemuatan halaman, tetapi tidak, ketika konten diubah oleh ajax. global $post;membantu saya di sini.

inilah solusi saya:

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

dalam hal ini, kueri bidang costum adalah: kecualikan semua posting, yang telah not_clickabledisetel ke true.

masalah lain yang saya temui: saya memiliki beberapa konten yang dibuat dan kemudian menerapkan bidang khusus itu sesudahnya .. jadi kueri juga mengecualikan posting yang bahkan tidak memiliki bidang yang dilampirkan pada posting, tidak peduli apakah benar atau salah. Ingatlah itu, saat menggunakan jenis penyaringan ini. pastikan bahwa setiap posting memiliki nilai atau pertimbangkan ini dalam sintaks sql Anda ..

membunyikan 31
sumber