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 , $query
zu 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_posts
Callback:
$query->set( 'page_id', get_option( 'page_on_front' ) );
Wenn ich den template_include
Filter 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_id
bei pre_get_posts
verursacht 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
, bar
und baz
sind 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
quelle
Antworten:
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()
forpage_id
undis_page
bewirkt nur, dass dasquery_vars
geä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:
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ückkehrtetrue
.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_vars
und eine Variable gibt$is_page
.Die von
set
Ihnen verwendete Funktion ($query->set( 'is_page', true );
) setzt nur eine Abfragevariable :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.quelle
$query->set( 'is_page', true )
vs ein wenig erklären$query->is_page = true
?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.
quelle
$query
Objekt und seinen Bedingungen passiert, ist ... etwas weniger als gut dokumentiert und kann immer noch ein Rätsel sein. :)