WordPress Admin Search: Erweitern der Ergebnisse

Veröffentlicht: 2021-01-20

Manchmal kann es schwierig sein, Inhalte auf einer Website zu finden. Als WordPress-Administrator ist es umso einfacher, die gewünschten Inhalte zu finden, desto besser. Glücklicherweise bietet WordPress eine Suchfunktion auf den meisten Admin-Bildschirmen, die Sie verwenden werden (z. B. auf dem Posts-Bildschirm). Obwohl diese Suchfunktion gut ist, ist sie dennoch in vielerlei Hinsicht eingeschränkt.

Wenn Sie beispielsweise auf dem Verwaltungsbildschirm für Beiträge nach einem Beitrag suchen, sucht die Suchfunktion standardmäßig nach dem Suchabfragetext im Beitragstitel, im Beitragsauszug und im Beitragsinhalt und gibt dann diese Ergebnisse zurück. Was aber, wenn Sie mit Schlüsselwörtern suchen möchten, die sich auf ein benutzerdefiniertes Feld beziehen? Diese Informationen sind nicht in den Suchergebnissen der Admin-Postlistentabelle enthalten, was frustrierend sein kann.

In einem früheren Artikel haben wir gelernt, wie man ein benutzerdefiniertes Feld in unseren Beitragstypen hinzufügt. Sehen wir uns an, wie wir auch ein benutzerdefiniertes Feld in die Suchergebnisse aufnehmen können.

Erweitern Sie die Suchanfrage in der Admin-Bildschirmsuche

In unserem ausgearbeiteten Beispiel zu benutzerdefinierten Feldern haben wir in einem unserer Beiträge ein benutzerdefiniertes Feld namens „Quelle“ erstellt und einen URL-Wert eingefügt.

Wenn Sie in die Posts-Listentabelle gehen und einen dieser „source“-Werte in der Suchleiste verwenden, erhalten Sie keine Ergebnisse, da WordPress bei der Suche standardmäßig einfach keine benutzerdefinierten Felder berücksichtigt.

Um dies zu ändern, müssen wir den ursprünglichen Hook erweitern, den WordPress für die Suchfunktion bereitstellt. Der Hook, den wir erweitern müssen, ist pre_get_posts , der in der Datei wp-includes/class-wp-query.php um Zeile 1779 innerhalb der Funktion get_posts ist.

Die WordPress-Abfrage

Jedes Mal, wenn Sie eine Seite besuchen, entweder in der Vorderansicht oder im Admin-Bereich, wird eine Kette von Codeskripten ausgeführt, um das Ihrer Anfrage entsprechende WP_Query Objekt zusammen mit seinen Eigenschaften zu erstellen.

Lassen Sie uns eine temporäre Ansicht einiger der Ausgabeeigenschaften der Abfrage erstellen, um zu verstehen, welche Änderungen in jedem Fall im WP_Query Objekt auftreten.

Um die Abfrage anzuzeigen, bevor sie ausgeführt wird, hängen wir den Ausdruck an den pre_get_posts an. Der pre_get_posts -Filter wird ausgelöst, nachdem das Abfragevariablenobjekt erstellt wurde, aber bevor die eigentliche Abfrage ausgeführt wird.

Fügen Sie in der Datei functions.php Ihres aktiven Designs diesen Code ein:

 add_action( 'pre_get_posts', 'print_query' ); function print_query( ) { print_r ( $GLOBALS['wp_query']->query ); echo "<hr>"; print_r ( $GLOBALS['wp_query']->query_vars ); echo "<hr>"; }

Wenn Sie jetzt den Posts-Admin-Bildschirm besuchen, werden die Ausgaben von query und query_var oben gedruckt.

Um den Code einfacher anzuzeigen, können Sie ihn kopieren und in einen kostenlosen Online-PHP-Beautifier einfügen.

Das $GLOBALS['wp_query']->query (first out) sieht folgendermaßen aus:

 Array ( [order] => [orderby] => [post_type] => post [posts_per_page] => 20 [post_status] => [perm] => )

Bei einer Suche beispielsweise im Posts-Admin-Bildschirm ändert sich die Array-Ausgabe einschließlich der Suchzeichenfolge. Wenn wir zum Beispiel nach „wordpress.org“ suchen, sieht das so aus:

 Array ( [m] => 0 [cat] => 0 [s] => wordpress.org [paged] => 1 [order] => [orderby] => [post_type] => post [posts_per_page] => 20 [post_status] => [perm] => )

Stellen Sie den Code zusammen

Unter Berücksichtigung der obigen Informationen werden wir den richtigen Code einfügen, um die von uns benötigte Suchfunktion zu erreichen. Gehen Sie dazu zurück zur Datei functions.php Ihres aktiven Designs und löschen Sie den Code, den Sie vor wenigen Augenblicken im vorherigen Schritt eingefügt haben. Dann fügen Sie den folgenden Code ein:

 add_action( 'pre_get_posts', 'extend_admin_search' ); function extend_admin_search( $query ) { $post_type = 'post'; $custom_fields = array("source",); if( ! is_admin() ) return; if ( $query->query['post_type'] != $post_type ) return; $search_term = $query->query_vars['s']; $query->query_vars['s'] = ''; if ( $search_term != '' ) { $meta_query = array( 'relation' => 'OR' ); foreach( $custom_fields as $custom_field ) { array_push( $meta_query, array( 'key' => $custom_field, 'value' => $search_term, 'compare' => 'LIKE' )); } $query->set( 'meta_query', $meta_query ); }; }

Der nächste Schritt besteht darin, die Variablen $post_type und $custom_fields auf Werte zu ändern, die Ihren Anforderungen entsprechen. Mal sehen, was wir im Code gemacht haben.

  • $post_type = 'post'; – Hier definieren wir den Beitragstyp, den wir durchsuchen möchten.
  • $custom_fields = array("source",); – Hier definieren wir die benutzerdefinierten Felder, die wir durchsuchen möchten.

Da wir mit dem pre_get_posts Hook arbeiten, ist es wichtig, in unserem Code sicherzustellen, dass wir unsere benutzerdefinierte Sucherweiterung anwenden, während wir uns auf der richtigen Seite befinden. Um WordPress anzuweisen, unseren Code unter bestimmten Bedingungen anzuzeigen, verwenden wir einige bedingte Tags.

  • Die if ( ! is_admin() ) return; Bedingung stellt sicher, dass keiner unserer Codes ausgeführt wird, wenn wir uns nicht im Admin-Bereich befinden.
  • Das if ( $query->query['post_type'] != $post_type ) prüft, ob wir an dem Posttyp arbeiten, den wir in der Variablen $post_type definiert haben. post Sie in unserem Fall .
  • Die $search_term = $query->query_vars['s']; Hier halten wir den Suchstring in einer Variablen und setzen ihn dann wieder auf leer $query->query_vars['s'] = ''; sonst findet er nichts.

Jetzt, da diese Aktualisierungen vorhanden sind, erhalten Sie die richtigen Ergebnisse, wenn Sie die letzte Suche aktualisieren. In unserem Fall sehen wir den Beitrag „Beitrag 1“ in den Ergebnissen, der einen benutzerdefinierten Feldeintrag „Quelle“ enthält: „https://dev. wordpress.org /reference/functions/add_post_meta/'.

Verbesserung der WordPress-Admin-Suche

Erweitern Sie die Suchanfrage in der Frontansichtssuche

Jetzt, wo wir unsere Admin-Suche „korrigiert“ haben, können wir mit der Verbesserung unserer Front-End-Suchfunktion fortfahren, damit unsere Website-Benutzer auch nach benutzerdefinierten Feldern suchen können.

So wie zuvor die Admin-Suche keine Ergebnisse für benutzerdefinierte Felder lieferte, liefert auch die Frontend-Suche keine Ergebnisse für benutzerdefinierte Felder.

Idealerweise möchten wir, dass Benutzer nach diesen Feldern suchen können. In diesem Beispiel haben wir ein benutzerdefiniertes „Quelle“-Feld in einem unserer Beiträge, das derzeit die URL „https://dev.wordpress.org/reference/functions/add_post_meta/“ enthält. Wenn ein Benutzer nach „wordpress.org“ sucht, sollte dieser Beitrag in den Ergebnissen angezeigt werden. Lassen Sie uns herausfinden, wie das geht.

Der erforderliche Code

Gehen Sie erneut zu Ihrer Datei functions.php und kopieren Sie den Code, den Sie zuvor eingefügt haben. Fügen Sie dies nun direkt unter diesem Code ein (so dass Sie zwei Kopien dieses Codes in functions.php haben). Ändern Sie nun den Namen der Funktion in diesem zweiten Codeabschnitt in etwas wie extend_front_search . Es sollte so aussehen:

 add_action( 'pre_get_posts', 'extend_admin_search' ); function extend_admin_search( $query ) { $post_type = 'post'; $custom_fields = array("source",); if( ! is_admin() ) return; if ( $query->query['post_type'] != $post_type ) return; $search_term = $query->query_vars['s']; $query->query_vars['s'] = ''; if ( $search_term != '' ) { $meta_query = array( 'relation' => 'OR' ); foreach( $custom_fields as $custom_field ) { array_push( $meta_query, array( 'key' => $custom_field, 'value' => $search_term, 'compare' => 'LIKE' )); } $query->set( 'meta_query', $meta_query ); }; }

Als nächstes müssen wir die if ( $query->query['post_type'] != $post_type ) return; Bedingung.

 add_action( 'pre_get_posts', 'extend_front_search' ); function extend_front_search( $query ) { $post_type = 'post'; $custom_fields = array("source",); if( is_admin() ) return; $search_term = $query->query_vars['s']; $query->query_vars['s'] = ''; if ( $search_term != '' ) { $meta_query = array( 'relation' => 'OR' ); foreach( $custom_fields as $custom_field ) { array_push( $meta_query, array( 'key' => $custom_field, 'value' => $search_term, 'compare' => 'LIKE' )); } $query->set( 'meta_query', $meta_query ); }; }

Wir müssen nur die Bedingung if( is_admin() ) return; um sicherzustellen, dass der Code nur im Frontend gilt und wir können loslegen.

Eine alternative Strategie

Eine weitere Möglichkeit, die WordPress-Suche um benutzerdefinierte Felder zu erweitern, besteht darin, die SQL-Abfrage zu ändern.

Die Klasse WP_Query hilft dir dabei, indem sie sie wie in Zeile 2897 der Datei wp-includes/class-wp-query.php beschrieben in Stücke zerlegt.

 $clauses = (array) apply_filters_ref_array( 'posts_clauses_request', array( compact( $pieces ), &$this ) ); $where = isset( $clauses['where'] ) ? $clauses['where'] : ''; $groupby = isset( $clauses['groupby'] ) ? $clauses['groupby'] : ''; $join = isset( $clauses['join'] ) ? $clauses['join'] : ''; $orderby = isset( $clauses['orderby'] ) ? $clauses['orderby'] : ''; $distinct = isset( $clauses['distinct'] ) ? $clauses['distinct'] : ''; $fields = isset( $clauses['fields'] ) ? $clauses['fields'] : ''; $limits = isset( $clauses['limits'] ) ? $clauses['limits'] : '';

Wie wir bereits in den Artikeln zu benutzerdefinierten Feldern erwähnt haben, werden alle benutzerdefinierten Felddaten in der Datenbank in der „postmeta“-Tabelle gespeichert, die standardmäßig nicht in der WordPress-Suche enthalten ist. Unser erster Schritt besteht also darin , diese beiden Tabellen mit dem folgenden Code zu verbinden :

 function join_meta_table( $join ) { global $wpdb; if ( is_search() ) { $join .=' LEFT JOIN '.$wpdb->postmeta. ' ON '. $wpdb->posts . '..post_id '; } return $join; } add_filter('posts_join', 'join_meta_table' );

Wir haben natürlich den posts_join Hook verwendet, da er die JOIN-Klausel der Abfrage filtert.

Als Nächstes verwenden wir den posts_where Hook, um den WHERE-Teil der Abfrage an unsere Anforderungen anzupassen.

 function modify_where_clause( $where ) { global $pagenow, $wpdb; if ( is_search() ) { $where = preg_replace( "/\(\s*".$wpdb->posts.".post_title\s+LIKE\s*(\'[^\']+\')\s*\)/", "(".$wpdb->posts.".post_title LIKE $1) OR (".$wpdb->postmeta.".meta_value LIKE $1)", $where ); } return $where; } add_filter( 'posts_where', 'modify_where_clause' );

Nicht zuletzt müssen wir Duplikate verhindern. Um dies zu erreichen, verwenden wir den posts_distinct Hook, der die DISTINCT-Klausel der Abfrage filtert.

 function prevent_duplicates( $where ) { global $wpdb; if ( is_search() ) { return "DISTINCT"; } return $where; } add_filter( 'posts_distinct', 'prevent_duplicates' );

Sehen wir uns nun an, was im Frontend passiert, wenn wir nach der Zeichenfolge „wordpress.org“ suchen.

WordPress-Suche im Frontend

Wie erwartet sind die Ergebnisse diesmal korrekt. Die WordPress-Suche hat als Ergebnis „post 1“ gefunden, da es das Feld „source“ mit dem Wert „https://dev. wordpress.org /reference/functions/add_post_meta/

Benutzerdefinierte Beitragstypen in WordPress-Suchergebnissen

Eine andere Sache, die Sie vielleicht tun möchten, ist, benutzerdefinierte Beitragstypen durchsuchbar zu machen (wenn Sie nicht sicher sind, wie Sie einen benutzerdefinierten Beitragstyp erstellen, lesen Sie unbedingt unsere Artikel dazu hier).

Stellen wir uns vor, wir haben einen benutzerdefinierten Beitragstyp namens „Bücher“ erstellt und möchten, dass dieser Beitragstyp in den Suchergebnissen angezeigt wird. Diesmal müssen wir die SQL-Abfrage nicht neu erstellen, sondern nur die Post-Typen im pre_get_posts -Hook neu definieren, wie unten beschrieben. Der Code muss noch einmal in die Datei functions.php eingefügt werden.

 function tg_include_custom_post_types_in_search_results( $query ) { if ( $query->is_main_query() && $query->is_search() && ! is_admin() ) { $query->set( 'post_type', array( 'post', 'books' ) ); } } add_action( 'pre_get_posts', 'tg_include_custom_post_types_in_search_results' );

Was wir hier getan haben, war, die gewünschten Beitragstypen, die in die Suchergebnisse aufgenommen werden sollen, als Argumente zum post_type Hook hinzuzufügen.

Wenn Sie einen Typ ausschließen möchten, entfernen Sie ihn einfach aus dem Array.

Fazit

Die Verbesserung der Suche auf Ihrer WordPress-Website kann sehr hilfreich sein und viel Zeit sparen. Für Ihre Endbenutzer ist es auch wichtig, dass sie sowohl nach benutzerdefinierten Beitragstypen als auch nach benutzerdefinierten Feldern suchen können. Hoffentlich haben Ihnen die obigen Anweisungen einen Einblick gegeben, wie Sie dies auf Ihrer eigenen Website erreichen können.