Wie erzwinge ich eine Abfragebedingung?


7

Es gibt einen langjährigen WordPress-Kernfehler ( # 16373 ), bei dem die Abfrage nicht auf is_front_page()true gesetzt wird, wenn benutzerdefinierte Abfragevariablen registriert sind und in der Abfragezeichenfolge vorhanden sind , selbst wenn 'page' == get_option( 'show_on_front' ). Ausführliche Informationen finden Sie im Trac-Ticket. Das Endergebnis ist jedoch, dass die Startseite anstelle von eine ungültige Seite zurückgibt get_option( 'page_on_front' ).

Ich habe einen bestimmten Anwendungsfall, in dem ich benutzerdefinierte Abfragevariablen an die Abfragezeichenfolge auf der Startseite übergeben muss (mithilfe eines Formulars zum Übergeben registrierter Abfragevariablen, die wiederum zum Filtern von Themenoptionen verwendet werden - eine Demo zu Front-End-Themenoptionen ). Das oben erwähnte Trac-Ticket wurde als ungültig geschlossen, daher brauche ich eine Problemumgehung.

Ich kann die Titelseitenvorlage einfach genug erzwingen, wie folgt:

function themeslug_force_front_page_template( $template ) {
    if ( '' != get_query_var( 'foobar' ) ) { // Registered custom query var
        return get_front_page_template();
    }
    return $template;
}
add_filter( 'template_include', 'themeslug_force_front_page_template' );

Die zugrunde liegenden Abfragebedingungen sind jedoch nicht betroffen. Code, der vom is_front_page()Sein abhängt true(z. B. ein Schieberegler, der nur auf der Startseite der Site angezeigt wird), wird daher immer noch nicht richtig gerendert.

Ich habe versucht , zu modifizieren , $queryzu pre_get_posts, aber dies scheint nicht zu funktionieren:

function themeslug_force_static_front_page( $query ) {
    if ( $query->is_main_query() ) {
        if ( 'page' == get_option( 'show_on_front' ) ) {
            if ( '' != get_query_var( 'foobar' ) ) { // Registered custom query var
                $query->set( 'page_id', get_option( 'page_on_front' ) );
                $query->set( 'is_home', false );
                $query->set( 'is_page', true );
                $query->set( 'is_front_page', true );
            }
        }
    }
}
add_action( 'pre_get_posts', 'themeslug_force_static_front_page' );

Die Abfragebedingungen werden nicht geändert. Versuche ich es falsch in meinem Rückruf? Gibt es eine andere / bessere Möglichkeit, insbesondere die Abfragebedingungen zu erzwingen is_front_page()?

Bearbeiten

Beachten Sie, dass die Einstellung page_id tut Arbeit im pre_get_postsCallback:

$query->set( 'page_id', get_option( 'page_on_front' ) );

Wenn ich den template_includeFilter weglasse , ist die angezeigte Seite tatsächlich die Seite, die der Startseite zugewiesen ist. wird jedoch get_page_template()eher verwendet als get_front_page_template(). Also, Einstellung page_idbei pre_get_postsverursacht is_page()wahr zu sein. Der oben genannte Fehler verhindert is_front_page()jedoch, dass er eingestellt wird true.

Bearbeiten 2

Per @ toschos Anfrage, hier ist ein Abfrage-Var-Code für den Kontext.

Abfragevariablen registrieren:

/**
 * Add options-related query variables
 */
function themslug_add_theme_demo_query_vars( $qvars ) {
    $qvars[] = 'demo_foo';
    $qvars[] = 'demo_bar';
    $qvars[] = 'demo_baz';
    return $qvars;
}
add_filter( 'query_vars', 'themeslug_add_theme_demo_query_vars' );

(Wo foo, barund bazsind Themenoptionen - Hintergrund, verschiedene Farben usw.)

Sie werden einfach verwendet, um einer Themenoption einen Filter hinzuzufügen - dieser Teil fällt nicht in den Geltungsbereich der Frage, daher werde ich ihn hier weglassen.

Sie werden am Frontend über ein benutzerdefiniertes Widget ausgegeben. Die Widget-Ausgabe ist nur ein Formular. Hier ist ein Beispiel für eines der Formularfelder:

<h3>Foo</h3>
<input name="demo_foo" id="demo_foo" class="pickcolor"  type="text" value="<?php echo $foo_setting; ?>" data-default-color="<?php echo $foo_setting; ?>" />

Generierte Abfragezeichenfolge beim Senden:

www.example.com/?foo=some_value

Können Sie einen einfachen Testfall hinzufügen, z. der Code, der die Abfrage var registriert?
Fuxia

Sicher, die Registrierung der Abfragevariablen funktioniert einwandfrei, und alles, was sie verwendet, funktioniert einwandfrei - aber ich werde ein Beispiel für den Kontext hinzufügen.
Chip Bennett

Antworten:


7

Haben Sie überprüft, welcher Teil von is_front_page () dazu führt, dass false zurückgegeben wird?

Ich könnte das Problem reproduzieren, indem ich dem Setup des Trac-Tickets folge. In meinem Fall innerhalb dieser Funktion wurde der Aufruf von is_page () zurückgegeben false.

Ich denke, dies liegt an der Verwendung von $wp_query->set()for page_idund is_pagebewirkt nur, dass das query_varsgeändert wird. Sie ändern den "Status der Abfrage" selbst nicht.

Ich konnte eine Problemumgehung dafür erstellen, indem ich diese beiden Zeilen an Ihren Code anhängte:

$query->is_page = true;
$query->queried_object = get_post(get_option('page_on_front') );

Dies führte (in meinem Setup) dazu, dass die Seite korrekt auf der Startseite angezeigt wurde (obwohl die query_var in der URL vorhanden war) und auch is_front_page()zurückkehrte true.

Ich hoffe das hilft dir etwas weiter.


Wenn Sie sich die Definition der WP_Query- Klasse ansehen , werden Sie feststellen , dass es eine Variable $query_varsund eine Variable gibt $is_page.

Die von setIhnen verwendete Funktion ( $query->set( 'is_page', true );) setzt nur eine Abfragevariable :

function set($query_var, $value) {
    $this->query_vars[$query_var] = $value;
}

Die Statusinformationen, in denen gespeichert wird $query->is_page = true, werden nicht geändert , sondern die Abfragevariable festgelegt $query->query_vars['is_page'] = true.

Das ist etwas irreführend, wenn Sie aus einem OOP-Ansatz stammen und WP_Query::set()als klassische Klassensetzfunktion verstehen - was es nicht ist.


1
+1. Das funktioniert auch an meinem Ende. Vielen Dank! Können Sie den "Status der Abfrage" im Zusammenhang mit $query->set( 'is_page', true )vs ein wenig erklären $query->is_page = true?
Chip Bennett

1
@ChipBennett Versucht, es ein bisschen mehr zu erklären.
s1lv3r

3

Ich habe auch in diesem Trac-Ticket geantwortet, aber ich denke, das Basisproblem hier ist viel einfacher als dieses.

Sie haken demo_foo, demo_bar, demo_baz als "Abfragevariablen" ein, aber das sind sie nicht. Zumindest nicht im beabsichtigten Sinne.

Während die? Foo = bar-Zeichenfolge nach der URL häufig als Abfragezeichenfolge bezeichnet wird, sind die "Abfragevariablen" eigentlich nur Variablen, die sich auf die Hauptabfrage auswirken. Wenn Sie eine Variable nicht einbinden, verschwindet sie nicht und wird vom Hauptobjekt WP_Query nicht gelesen.

Und in Ihrem Fall scheint das genau das zu sein, was Sie wollen. Ihre Variablen sind Themenoptionen und nicht Teil der Hauptabfrage (die Beiträge aus der Datenbank abruft). Sie verwenden sie nicht, um auszuwählen, welche Beiträge angezeigt werden sollen, sondern um Themenoptionen und dergleichen festzulegen.

Wenn Sie sie nicht als query_vars einbinden, wirken sie sich überhaupt nicht auf das Hauptobjekt WP_Query aus. Sie müssen sie vom Hauptglobal $ _GET abrufen, anstatt get_query_var zu verwenden, und Sie müssen sie ordnungsgemäß bereinigen, um reflektierende XSS-Angriffe zu verhindern (mit esc_attr oder was auch immer angemessen ist). Dies sollte jedoch Ihr primäres Problem lösen, indem Sie es beseitigen Der Code, der das Problem verursacht, anstatt eine zusätzliche Problemumgehung hinzuzufügen.


Das spricht sicherlich meinen spezifischen Anwendungsfall an (und zeigt, warum der Fehlerbericht ungültig bleibt) - aber die zugrunde liegende Frage war, wie die Abfragebedingung geändert werden kann. Was mit dem $queryObjekt und seinen Bedingungen passiert, ist ... etwas weniger als gut dokumentiert und kann immer noch ein Rätsel sein. :)
Chip Bennett
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.