Ich wollte pages
aus den Suchergebnissen ausschließen und habe viele Möglichkeiten gefunden, dies zu tun. Ich habe mich gefragt, warum !is_admin()
oder is_main_query()
verwendet wird und welcher Weg besser ist.
add_filter('pre_get_posts','search_filter');
function search_filter($query) {
if ($query->is_search) {
$query->set('post_type', 'post');
}
return $query;
}
add_filter('pre_get_posts','search_filter');
function search_filter($query) {
if ( !is_admin() && $query->is_search) {
$query->set('post_type', 'post');
}
return $query;
}
add_action('pre_get_posts','search_filter');
function search_filter($query) {
if ( !is_admin() && $query->is_main_query() ) {
if ($query->is_search) {
$query->set('post_type', 'post');
}
}
}
Beachten Sie, dass, wenn wir verwenden:
$query->set( 'post_type', 'post' );
dann überschreiben wir alle durchsuchbaren Beitragstypen, nicht nur den Beitragstyp page
.
In einigen Fällen ist das in Ordnung, und wir haben einige Ihrer pre_get_posts
-Snippets verwendet, die unseren Anforderungen entsprechen.
Aber manchmal wollen wir es nicht so fest machen. Hier diskutieren wir solche Szenarien.
Verwenden des Filters register_post_type_args.
Wenn der Beitragstyp nicht angegeben ist, werden bei der Suche nach WP_Query
alle durchsuchbaren Beitragstypen verwendet, und zwar :
$in_search_post_types = get_post_types( array('exclude_from_search' => false) );
Wenn wir einen Beitragstyp registrieren, können wir den Parameter exclude_from_search
auf false setzen, um ihn von der Suche auszuschließen.
Wir können es für die Einrichtung des Post-Typs page
ändern mit:
add_filter( 'register_post_type_args', function( $args, $name )
{
// Target 'page' post type
if( 'page' === $name )
$args['exclude_from_search'] = true;
return $args;
}, 10, 2 );
Mehr über register_post_type()
hier .
Beispiele
In den folgenden Beispielen wird der Seitenzugriffstyp mithilfe der obigen Filterung von der Suche ausgeschlossen:
Hauptabfragesuche im Frontend mit
https://example.tld?s=testing
Sekundäre Abfrage wie:
$query = new WP_Query( [ 's' => 'testing' ] );
Sekundäre Abfrage wie:
$query = new WP_Query( [ 's' => 'testing', 'post_type' => 'any' ] );
Einige Hinweise zu Abfragen mit voreingestellten Beitragstypen:
Betrachten wir Fälle, in denen die Post-Typen behoben sind, wie:
$query = new WP_Query( [ 's' => 'testing', 'post_type' => [ 'page', 'post'] ] );
Wenn der Beitragstyp durch einen Array $post_type
festgelegt ist, können wir den 'page'
herausfiltern
if( is_array( $post_type ) && count( $post_type ) > 1 )
{
$post_type = array_filter(
$post_type,
function( $item ) { return 'page' !== $item; }
);
}
Wenn wir keinen direkten Zugriff auf dieses Array haben, könnten wir z. pre_get_posts
, um die 'Seite' mit Hilfe der get
/set
-Methoden von WP_Query
aus dem Post-Typ-Array zu entfernen. Hier ist ein Beispiel für die Hauptsuchabfrage im Frontend:
add_action( 'pre_get_posts', function search_filter( \WP_Query $query )
{
if( ! $query->is_search() || ! $query->is_main_query() || ! is_admin() )
return;
$post_type = $query->get( 'post_type' );
if( is_array( $post_type ) && count( $post_type ) > 1 )
{
$post_type = array_filter(
$post_type,
function( $item ) { return 'page' !== $item; }
);
$query->set('post_type', $post_type );
}
} );
Warum haben wir hier die Arrayanzahl> 1 überprüft?
Das liegt daran, dass wir darauf achten sollten, 'page'
aus Beispielen wie den folgenden zu entfernen:
$query = new WP_Query( [ 's' => 'testing', 'post_type' => [ 'page' ] ] );
$query = new WP_Query( [ 's' => 'testing', 'post_type' => 'page' ] );
als leeres Array oder als leere Zeichenfolge für den Beitragstyp:
$query = new WP_Query( [ 's' => 'testing', 'post_type' => [] ] );
$query = new WP_Query( [ 's' => 'testing', 'post_type' => '' ] );
wird auf den Beitragstyp 'post'
zurückgreifen.
Beachten Sie, dass:
$query = new WP_Query( [ 's' => 'testing', 'post_type' => 'page, post' ] );
wird nicht unterstützt, da der resultierende Beitragstyp 'pagepost'
wäre.
In diesen Fällen, in denen wir keinen direkten Zugriff auf die WP_Query
-Objekte haben, können wir die Abfrage mit Tricks wie 'post__in' => []
oder 1=0
in der Suche unterbrechen, wenn eine WHERE-Abfrage ausgeführt wird, oder sogar mit dem posts_pre_query
-Filter oder mit erweiterten Methoden spielen. Darüber gibt es auf dieser Site viele Antworten. Das und das ist das, woran ich mich im Moment erinnere.
Der null
Fall:
$query = new WP_Query( [ 's' => 'testing', 'post_type' => null ] );
greift auf 'any'
Beitragstypen zurück:
Ich hoffe es hilft!
PS:
Beachten Sie auch die Inkonsistenz in Ihren Snippets, da Sie beide haben
add_filter('pre_get_posts','search_filter');
und
add_action('pre_get_posts','search_filter');
Es wird als eine Aktion betrachtet, aber es macht keinen Unterschied, da Aktionen hinter den Kulissen als Filter verpackt sind.
pre_get_posts
wird sowohl im Admin als auch im Frontend ausgeführt. Sie können es verwenden, um Beiträge zu filtern, die den Admin-Benutzern angezeigt werden, sowie Frontend-Ergebnisse. Durch das Hinzufügen von ! is_admin()
wird sichergestellt, dass sich dieser Code nur auf das Frontend auswirkt.
is_main_query()
stellt sicher, dass Sie nur die Abfrage für die Posts beeinflussen, nicht beispielsweise die Menüelemente in der Navigationsleiste oder eine Liste der Posts in der Seitenleiste. Es wird empfohlen, das zu verwenden.
Lassen Sie mich wissen, wenn dies nicht klar ist,