Der abgefragte Post im pre_get_posts-Hook kann nicht gewechselt werden

Ich muss basierend auf der URL dynamisch ändern, welche Seite geladen wird. Es ist ein Übersetzungssystem und der Slug einer Seite ist für jede Sprache unterschiedlich. URLs sehen so aus:

/en/best-restaurants-in-tokyo /it/migliori-ristoranti-a-tokyo /fr/meilleurs-restaurants-à-tokyo 

Die Schnecken werden in einer separaten Tabelle gespeichert, nicht in wp_posts oder wp_postmeta . Die einzige Möglichkeit, die ich gefunden habe, ist das Ändern des globalen WP_Query Objekts im pre_get_posts Hook. Das Problem ist, dass es nicht funktioniert und ich verstehe nicht warum. WordPress rendert index.php statt single.php wie es für alle Posts sein sollte. Wenn ich die Seite nach dem Original-Slug oder nach ID öffne (zB ?p=4033 ), funktioniert alles einwandfrei.

Unten ist der Code, der das Problem veranschaulicht.

 add_action('pre_get_posts', 'mt_handle_translation_redirect', 9999); function mt_handle_translation_redirect ($query) { global $wpdb; if (!$query->is_main_query()) return; // "1178" is a valid post ID $query->set('page_id', 1178); } 

Wenn ich eine Post-Seite öffne (zB ‘ http: // localhost / wordpress /? P = 1010 ‘), wird sie wie erwartet auf die Seite 1178 umgeleitet. Wenn ich eine Homepage öffne, werden keine Weiterleitungen ausgeführt.

Wenn wir add_rewrite_rule zum Code hinzufügen, werden keine Weiterleitungen mehr korrekt ausgeführt, stattdessen wird versucht, die Startseite zu rendern:

 add_action('init', 'mt_init'); function mt_init() { add_rewrite_tag('%tr_language%', '([a-z_-]+)' ); add_rewrite_tag('%tr_title%', '([\pL_-]+)' ); add_rewrite_rule('^(fr)/([^/]+)/?', 'index.php?tr_language=$matches[1]&tr_title=$matches[2]', 'top'); flush_rewrite_rules(); } 

Es scheint, dass wenn ich index.php ohne die spezifische Post-ID oder einen Slug anrufe, es nicht mehr möglich ist, eine Weiterleitung zu einer anderen Seite durchzuführen, weil es immer eine Post-Liste wie auf einer Homepage oder einer Kategorieseite darstellt.

Wie erstelle ich benutzerdefinierte URLs, um einen anderen Beitrag zu öffnen?

Solutions Collecting From Web of "Der abgefragte Post im pre_get_posts-Hook kann nicht gewechselt werden"

Huh. Ich habe es überprüft. Auf meinem lokalen Server ändert dieser Codecode den Post erfolgreich:

 function test_redirect() { global $wp_query; $wp_query->set('page_id', 5); } add_action('pre_get_posts', 'test_redirect'); 

Du musst ein bisschen debuggen. Auf einem Dev-Server, var_dump die $ wp_query-Variable ein paar wichtige Stellen, um zu überprüfen, dass es das hat, was Sie erwarten.

Eine alternative Lösung besteht darin, die Aktion parse_query anzuhängen , um die Abfrage früher zu ändern.

Eine andere Möglichkeit besteht darin, später in template_redirect einzuhaken und dann ein brandneues wp_query-Objekt zu erstellen. Dies wäre im Allgemeinen vorzuziehen, wenn Sie den Post zu etwas grundlegend anderem statt nur einer anderen Übersetzung ändern würden, weil es alle anderen Variablen löscht, die zuvor von parse_query gesetzt wurden. Es bringt den zusätzlichen Aufwand mit sich, zweimal nach dem Post zu fragen. Hier ist die allgemeine Idee:

 function redirect_translation() { global $wp_query; // Replace wp_query here... query_posts() should work too. $wp_query = new WP_Query(array('post_id' => 5)); } add_action('template_redirect','redirect_translation'); 

Wenn Sie dies in pre_get_posts tun, wird eine Endlosschleife ausgetriggers.

EDIT: Wie sieht es mit dem Aufruf von mt_handle_translation_redirect aus ? Ich vermute, dass Sie möglicherweise das globale $ wp_query-Objekt nicht aktualisieren, weshalb die echte Abfrage nicht geändert wird. Das Überprüfen des Inhalts von wp_query an einigen Stellen (wie der Vorlagedatei) wäre ein guter Anfang.