meta_keyでnext_post_link()およびprevious_post_link()をフィルタリングしますか?


8

私は2つのセクションを持つページを持っています。セクションごとに異なるWP_Query()を使用しeventsて、カスタム投稿タイプです。それぞれがイベント日付についてWP_Query()a meta_keyを照会し、セクション1は次の日付のみを表示しevents、セクション2は過去の日付を表示しますevents

次のeventsセクション1では、私のページにすべての関連情報が表示されるため、それらをクリックすることはできません。

eventsセクション2 の過去はeventタイトルのみを表示し、クリック可能です。ユーザーが過去eventをクリックすると、過去のカスタムsingle-event.phpテンプレートにリンクしeventます。

single-event.phpテンプレートに前/次のナビゲーションを表示したいのですが、ナビゲーションは過去をポイントするだけeventsです。

私は使っnext_post_link()てみましたprevious_post_link()が、これらも次のリンクにつながりeventsます。私はセットアップ新しいおそらくすることができWP_Query()、私のsingle-event.php前/次のIDを取得することによって、ループを、しかし、クエリを繰り返して抜本的なステップのように思えます。

events前の投稿/次の投稿のリンクからの今後の投稿を除外する方法についての洞察をいただければ幸いです。この質問を見たことがありますが、プラグインを使用したくないです。


1
これに対する答えは、リンクした質問に対する他の答えにほのめかされていget_adjacent_postます。関数のjoin / where / sort句をフィルタリングする必要があります。
ミロ2014年

はいそれはほのめかされています。できれば実際に動作する例を見たいです。
cfx

1
現時点でコードを作成する時間はありませんが、まず最初にを介してクエリを実行しWP_Query、次にを検査することから始めます$your_query_object->request。これにより、プルする必要のあるSQLのかなりの部分が明らかになります。
ミロ

ヒント@Miloをありがとう、私はそれを理解したと思います!下記参照!
cfx 2014年

回答:


6

@Miloのヒントのおかげで、WordPressフィルターのみを使用してこれを機能させることができました。

これらは私のケースにかなり特有のものですが、自分で使用するためにそれらを変更する問題はないはずです。私は、高度なカスタムフィールドを使用して、日付ピッカーフィールドを呼び出しdate、[前へ] / [次へ]リンクは、dateフィールドを今日の前日に設定したイベントのみを指します。

5つのフィルターを作成しました。

  • 変更するJOIN(追加するwp_postmeta)1
  • 1でWHERE前のリンクに変更
  • WHERE次のリンク用に変更するには1
  • 1でSORT前のリンクに変更
  • SORT次のリンク用に変更するには1

これが私が思いついたものです、それは機能しているようですが、誰かが何か問題を見つけたら、私はフィードバックが大好きです:

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

私はかなり似た問題を抱えていました。前/次のナビゲーションからいくつかの投稿をソートして除外する必要がありました。@cfxのソリューションの問題は次のとおりでした:ajaxには対応していませんis_singular()。wp-ajaxを介してコンテンツをロードすると、関数はfalseを返します。そのため、ページの読み込みには機能しましたが、ajaxによってコンテンツが変更されたときには機能しませんでした。global $post;ここで私を助けていました。

これが私の解決策です:

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

この場合、costumフィールドクエリは、cfがにnot_clickable設定されているすべての投稿を除外しtrueます。

別の問題が発生しました:一部のコンテンツを作成し、その後、そのカスタムフィールドを実装しました。そのため、クエリは、trueまたはfalseに関係なく、そのフィールドが投稿に関連付けられていない投稿も除外しました。このタイプのフィルタリングを使用する場合は、その点に注意してください。すべての投稿に値があることを確認するか、SQL構文でこれを考慮してください。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.