Durch das Hinzufügen eines Endpunkts zum Umschreiben wird die statische Startseite unterbrochen

7

Ich habe eine statische Startseite für mein WP-Installationsset von settings > reading. Dann habe ich mit einen URL-Endpunkt hinzugefügt.

add_rewrite_endpoint('foo', EP_ALL);

Die Titelseite sollte also über zugänglich sein

http://example.com/
http://example.com/foo
http://example.com/foo/bar

Für # 1 funktioniert alles einwandfrei, aber für # 2 und # 3 home.phpwird anstelle der statischen Homepage die Standardeinstellung angezeigt. Lokal in Einzel- und Multisite-Installation getestet.

Ist es ein gewünschtes Verhalten oder treffe ich etwas Ungewöhnliches? Noch wichtiger ist, wie kann ich WP dazu bringen, die statische Homepage unter den gegebenen Bedingungen anzuzeigen?

Lösung

Ich habe mich bereits eingehakt parse_request, um einen Teil des Codes zu verarbeiten, falls foovorhanden. Also, gemäß der Lösung von @ gmazzap. Ich muss es erst danach deaktivieren. Es ist keine zusätzliche Hakenfunktion erforderlich, um den Fehler zu umgehen.

add_action('parse_request', function(&wp){

    $key = 'foo';

    if (!array_key_exists( $key, $wp->query_vars ) ) {
        return;
    }

    // do things when foo exists

    // we no longer need 'foo'
    unset($wp->query_vars[$key]);

});
Sisir
quelle
1
ah Okey. Dann ist es ein Fehler. Ticket für 22 Monate geöffnet! Ich bin nur froh, dass es behoben ist!
Sisir

Antworten:

4

Vielleicht habe ich das nicht sehr gut verstanden, aber wenn Sie nur 'foo'aus der Abfrage entfernen müssen, wäre es nicht viel einfacher, den 'request'Filter zu verwenden und die Variable von dort zu entfernen?

Code benötigt:

add_filter('request', function($query_vars) {
     return array_diff_key($query_vars, array('foo'=>''));
});

Es:

  • läuft nur auf Hauptabfrage
  • Entfernen Sie die Variable für das $wpObjekt
  • wirkt, bevor die Abfrage aktiviert wird $wp_query, sodass die Abfrage nicht von dort entfernt werden muss
  • wirkt sich nicht auf alle anderen Variablen aus

Bearbeiten:

Ein Problem dieses Codes besteht darin, dass er sehr früh ausgeführt wird, so dass es schwierig ist, das Vorhandensein der Abfragevariablen zu erfassen und etwas basierend auf ihrem Vorhandensein / Wert zu tun.

Eine Lösung kann darin bestehen, die Bedingungen auf demselben 'request'Filter auszuführen , kurz bevor die Abfragevariable entfernt wird (z. B. mit demselben Hook mit höherer Priorität).

Eine andere Lösung kann darin bestehen, dem $wpObjekt ein Flag hinzuzufügen :

add_filter('request', function($query_vars) {
     $GLOBALS['wp']->_foo = isset($query_vars['foo']) ? $query_vars['foo'] : false;
     return array_diff_key($query_vars, array('foo'=>''));
});

Danach wäre es möglich, die Variable 'foo' in jedem Hook zu überprüfen, der danach ausgelöst 'request'wird'parse_request'

add_action('parse_request', function($wp) {
    $foo = $wp->_foo;
    // do something with foo
});

Der letzte ist 'shutdown':

add_action('shutdown', function() {
    $foo = $GLOBALS['wp']->_foo;
    // do something with foo
});
gmazzap
quelle
Wird dieses Entfernen foovon $wp->query_varsauf parse_requestAction? Ich führe bedingten Code aus, parse_requestwenn foovorhanden.
Sisir
@Sisir ja, wie Sie in der Quelle core.trac.wordpress.org/browser/tags/4.2.2/src/wp-includes/… sehen können, wird der 'request' Haken zuvor ausgelöst 'parse_request'. Sie können Ihre Bedingung in den requestHook verschieben oder 'parse_request'zum Entfernen der Variablen verwenden, nachdem Sie etwas basierend auf der 'foo'Präsenz getan haben . Ich habe auch das A bearbeitet, um einen dritten Ansatz aufzunehmen.
gmazzap
Genau richtig! Da bin ich schon dran parse_request. Das Entfernen fooaus der Abfrage var, nachdem ich damit fertig bin, erscheint angemessener. Ich brauche unset($wp->query_vars['foo']);nur kurz bevor ich meine Hook-Funktion in beende parse_request. Vielen Dank für Ihre Hilfe.
Sisir
4

Dies ist ein Fehler 25143, wie @toscho hervorhob und in 4.3 behoben wird

Problemumgehung Im Ticket gefunden und ein wenig geändert

WordPress fügt fooals Abfragevariable hinzu , die das Problem verursacht. Wir müssen es also entfernen, bevor WP die Datenbank abfragt

add_action( 'pre_get_posts', 'wpse191771_unset_query_arg' );
function wpse191771_unset_query_arg($query){

    if ( is_admin() || ! $query->is_main_query() ) {
        return;
    }

    $key = 'foo';

    $query_vars =& $query->query_vars;

    if ( array_key_exists($key, $query_vars) ) {
        // unset ref var from $wp_query
        $query->set( $key, null );

        global $wp;
        // unset ref var from $wp
        unset( $wp->query_vars[ $key ] );

        // if in home (because $wp->query_vars is empty) and 'show_on_front' is page
        if ( empty( $wp->query_vars ) && get_option( 'show_on_front' ) === 'page' ) {
            // reset and re-parse query vars
            $wp->query_vars['page_id'] = get_option( 'page_on_front' );
            $query->parse_query( $wp->query_vars );
        }
    }

}
Sisir
quelle