it-swarm.com.de

Next_post_link () und previous_post_link () nach meta_key filtern?

Ich habe eine Seite mit zwei Abschnitten, von denen jeder eine andere WP_Query() verwendet, um events einzugeben. Hierbei handelt es sich um einen benutzerdefinierten Beitragstyp. Jede WP_Query() fragt einen meta_key nach dem Ereignisdatum ab, sodass in Abschnitt 1 nur die nächste events und in Abschnitt 2 die frühere events angezeigt wird.

Die bevorstehende events in Abschnitt 1 zeigt alle relevanten Informationen auf meiner Seite an, sodass ein Anklicken nicht möglich ist.

Die vorherigen events in Abschnitt 2 zeigen nur den event-Titel an und sind anklickbar. Wenn Benutzer auf eine frühere event klicken, wird eine Verknüpfung zu einer benutzerdefinierten single-event.php-Vorlage für die frühere event erstellt.

Ich möchte die vorherige/nächste Navigation in der Vorlage single-event.php anzeigen, aber die Navigation sollte nur auf die vorherige events verweisen.

Ich habe versucht, next_post_link() und previous_post_link() zu verwenden, aber diese verweisen auch auf kommende events, die ich nicht möchte. Ich kann wahrscheinlich eine neue WP_Query() auf meinem single-event.php einrichten und diese durchlaufen, um die vorherigen/nächsten IDs zu erhalten, aber das Wiederholen der Abfrage scheint ein drastischer Schritt zu sein.

Ich würde mich sehr über einen Einblick darüber freuen, wie ich kommende events aus meinen Links zum vorherigen/nächsten Beitrag herausfiltern kann. Ich habe diese Frage gesehen aber ich würde es vorziehen, kein Plugin zu verwenden.

8
cfx

Dank des @ Milo-Hinweises habe ich es geschafft, dass dies nur mit WordPress-Filtern funktioniert.

Beachten Sie nur, dass diese für meinen Fall ziemlich spezifisch sind, aber Sie sollten kein Problem damit haben, sie für Ihren eigenen Gebrauch zu modifizieren. Ich verwende erweiterte benutzerdefinierte Felder mit einem Datumsauswahlfeld namens "date" und "Vorherige/Nächste Links", die nur auf Ereignisse verweisen, bei denen date-Felder auf einen Tag vor dem heutigen Tag gesetzt sind.

Ich habe 5 Filter erstellt:

  • 1, um JOIN zu ändern (um wp_postmeta hinzuzufügen)
  • 1, um WHERE für den Link Zurück zu ändern
  • 1, um WHERE für den Link Weiter zu ändern
  • 1, um SORT für den Link Zurück zu ändern
  • 1, um SORT für den Link Weiter zu ändern

Hier ist, was ich mir ausgedacht habe, es scheint zu funktionieren, aber wenn jemand irgendwelche Probleme entdeckt, würde ich mich über Feedback freuen:

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

ich hatte ein ziemlich ähnliches Problem, musste mehrere Beiträge sortieren und von der vorherigen/nächsten Navigation ausschließen. Das Problem mit der Lösung von @ cfx war: Es ist nicht für Ajax geeignet: Die Funktion is_singular() gibt false zurück, wenn Sie Inhalte über wp-ajax laden. Es funktionierte also beim Laden der Seite, tat es aber nicht, als der Inhalt von Ajax geändert wurde. global $post; hat mir hier geholfen.

hier ist meine Lösung:

/**
  * 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 diesem Fall lautet die Abfrage im Kostümfeld: Alle Posts ausschließen, für die not_clickable auf true gesetzt ist.

ein weiteres Problem, auf das ich gestoßen bin: Ich hatte einige Inhalte erstellt und anschließend dieses benutzerdefinierte Feld implementiert. Die Abfrage schloss daher auch die Posts aus, bei denen dieses Feld nicht einmal an den Post angehängt war, egal ob wahr oder falsch. Denken Sie daran, wenn Sie diese Art der Filterung verwenden. Stellen Sie sicher, dass jeder Beitrag einen Wert hat, oder berücksichtigen Sie dies in Ihrer SQL-Syntax.

3
honk31