Wyszukiwanie administratora WordPress: rozszerzanie wyników
Opublikowany: 2021-01-20Czasami znalezienie treści na stronie internetowej może być trudne. Jako administrator WordPress, im łatwiej jest znaleźć poszukiwane treści, tym lepiej. Na szczęście WordPress zapewnia funkcję wyszukiwania na większości ekranów administracyjnych, z których będziesz korzystać (na przykład na ekranie Posty). Chociaż ta funkcja wyszukiwania jest dobra, jest jednak ograniczona na wiele sposobów.
Na przykład, jeśli szukasz posta na ekranie administratora postów, funkcja wyszukiwania domyślnie wyszuka tekst zapytania w tytule posta, fragmencie posta i treści posta, a następnie zwróci te wyniki. Ale co, jeśli chcesz wyszukiwać za pomocą słów kluczowych powiązanych z polem niestandardowym? Te informacje nie są uwzględniane w wynikach wyszukiwania w tabeli listy postów administratora, co może być frustrujące.
W poprzednim artykule dowiedzieliśmy się, jak dodać niestandardowe pole w naszych typach postów. Przyjrzyjmy się również, jak możemy uwzględnić niestandardowe pole w wynikach wyszukiwania.
Rozszerz zapytanie wyszukiwania w wyszukiwaniu na ekranie administratora
W naszym roboczym przykładzie z polami niestandardowymi utworzyliśmy niestandardowe pole o nazwie „źródło” w jednym z naszych postów i wstawiliśmy wartość adresu URL.

Jeśli przejdziesz do tabeli z listą postów i użyjesz jednej z tych wartości „źródło” w pasku wyszukiwania, nie otrzymasz żadnych wyników, ponieważ WordPress po prostu domyślnie nie patrzy na pola niestandardowe podczas wyszukiwania.

Aby to zmienić, musimy rozszerzyć oryginalny hak, który WordPress zapewnia dla funkcji wyszukiwania. Haczyk, który musimy rozszerzyć, to pre_get_posts
, który jest zawarty w pliku wp-includes/class-wp-query.php
wokół wiersza 1779 wewnątrz funkcji get_posts
.
Zapytanie WordPress
Za każdym razem, gdy odwiedzasz stronę, w widoku z przodu lub w obszarze administracyjnym, wykonywany jest łańcuch skryptów kodu w celu utworzenia obiektu WP_Query
odpowiadającego Twojemu żądaniu wraz z jego właściwościami.
Utwórzmy tymczasowy widok niektórych wyników właściwości zapytania, aby zrozumieć, jakie zmiany zachodzą w obiekcie WP_Query
w każdym przypadku.
Aby wyświetlić zapytanie przed jego wykonaniem, dołączymy wydruk w haczyku akcji pre_get_posts
. Filtr pre_get_posts
uruchamiany po utworzeniu obiektu zmiennej zapytania, ale przed faktycznym uruchomieniem zapytania.
W pliku functions.php
aktywnego motywu wstaw ten fragment kodu:
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>"; }
Teraz, jeśli odwiedzisz ekran administratora postów, wyniki query
i zapytania query_var
zostaną wydrukowane na górze.

Aby łatwiej wyświetlić kod, możesz go skopiować i wkleić do bezpłatnego programu do upiększania PHP.
Tablica $GLOBALS['wp_query']->query
(pierwsza wyjściowa) będzie wyglądać tak:
Array ( [order] => [orderby] => [post_type] => post [posts_per_page] => 20 [post_status] => [perm] => )
Na przykład w przypadku wyszukiwania na ekranie administratora postów dane wyjściowe tablicy zmienią się, w tym ciąg wyszukiwania. Jeśli wyszukamy na przykład „wordpress.org”, będzie to wyglądać tak:
Array ( [m] => 0 [cat] => 0 [s] => wordpress.org [paged] => 1 [order] => [orderby] => [post_type] => post [posts_per_page] => 20 [post_status] => [perm] => )
Złóż kod
Mając na uwadze powyższe informacje, wstawimy prawidłowy kod, aby uzyskać wymaganą funkcję wyszukiwania. Aby to zrobić, wróć do pliku functions.php
aktywnego motywu i usuń kod, który wstawiłeś kilka chwil temu w poprzednim kroku. Następnie wprowadź poniższy kod:
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 ); }; }
Następnym krokiem jest zmiana $post_type
i $custom_fields
custom_fields na wartości odpowiadające Twoim wymaganiom. Zobaczmy, co zrobiliśmy w kodzie.
-
$post_type = 'post';
– Tutaj definiujemy typ posta, który chcemy przeszukać. -
$custom_fields = array("source",);
– Tutaj definiujemy niestandardowe pola, które chcemy przeszukać.
Ponieważ pracujemy z hakiem pre_get_posts
, ważne jest, aby upewnić się w naszym kodzie, że stosujemy nasze niestandardowe rozszerzenie wyszukiwania, gdy jesteśmy na właściwej stronie. Aby powiedzieć WordPressowi, aby wyświetlał nasz kod w określonych warunkach, używamy kilku tagów warunkowych.
-
if ( ! is_admin() ) return;
Warunek zapewnia, że jeśli nie znajdujemy się w obszarze administracyjnym, żaden z naszych kodów nie zostanie wykonany. -
if ( $query->query['post_type'] != $post_type )
sprawdza, czy pracujemy na typie posta, który zdefiniowaliśmy w zmiennej$post_type
. W naszym przypadkupost
. -
$search_term = $query->query_vars['s'];
to miejsce, w którym trzymamy szukany ciąg w zmiennej, a następnie ustawiamy go ponownie na pusty$query->query_vars['s'] = '';
inaczej nic nie znajdzie.
Teraz, po wprowadzeniu tych aktualizacji, jeśli odświeżysz ostatnie wyszukiwanie, otrzymasz prawidłowe wyniki. W naszym przypadku w wynikach widzimy wpis „Opublikuj 1”, który zawiera wpis w polu niestandardowym „źródło”: „https://dev. wordpress.org /reference/functions/add_post_meta/'.

Rozszerz zapytanie wyszukiwania w wyszukiwarce z widokiem z przodu
Teraz „naprawiliśmy” naszą wyszukiwarkę administracyjną, możemy przejść do ulepszania naszej funkcji wyszukiwania front-end, aby użytkownicy naszej witryny mogli również wyszukiwać pola niestandardowe.
W ten sam sposób, w jaki poprzednio wyszukiwanie administracyjne nie przynosiło żadnych wyników dla pól niestandardowych, wyszukiwanie w interfejsie również nie zwraca żadnych wyników dla pól niestandardowych.


W idealnej sytuacji chcielibyśmy, aby użytkownicy mogli wyszukiwać te pola. W tym przykładzie mamy niestandardowe pole „źródło” w jednym z naszych postów, które obecnie zawiera adres URL „https://dev.wordpress.org/reference/functions/add_post_meta/”. Jeśli użytkownik wyszukuje „wordpress.org”, ten post powinien pojawić się w wynikach. Dowiedzmy się, jak to zrobić.
Wymagany kod
Przejdź ponownie do pliku functions.php i skopiuj kod, który wkleiłeś wcześniej. Teraz wklej to bezpośrednio pod tym kodem (więc masz dwie kopie tego kodu w functions.php
) Teraz zmień nazwę funkcji w drugiej partii kodu na coś w rodzaju extend_front_search
. To powinno wyglądać tak:
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 ); }; }
Następnie musimy usunąć if ( $query->query['post_type'] != $post_type ) return;
stan.
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 ); }; }
Musimy tylko utrzymać warunek if( is_admin() ) return;
aby upewnić się, że kod będzie obowiązywał tylko w interfejsie użytkownika i jesteśmy gotowi do pracy.
Alternatywna strategia
Innym sposobem rozszerzenia wyszukiwania WordPress o pola niestandardowe jest zmiana zapytania SQL.
Klasa WP_Query
pomaga w tym, dzieląc ją na kawałki, jak opisano w wierszu 2897 pliku wp-includes/class-wp-query.php
.
$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'] : '';
Jak wspomnieliśmy wcześniej w artykułach o polach niestandardowych, wszystkie dane pól niestandardowych są przechowywane w bazie danych w tabeli „postmeta”, która domyślnie nie jest uwzględniana w wyszukiwaniu WordPress. Więc naszym pierwszym krokiem jest połączenie tych dwóch tabel za pomocą poniższego kodu:
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' );
Oczywiście użyliśmy haka posts_join
, ponieważ filtruje on klauzulę JOIN zapytania.
Następnie użyjemy zaczepu posts_where
, aby zmienić fragment zapytania WHERE, aby spełnić nasze potrzeby.
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' );
Wreszcie musimy zapobiegać duplikatom. Aby to osiągnąć, używamy haka posts_distinct
, który filtruje klauzulę DISTINCT zapytania.
function prevent_duplicates( $where ) { global $wpdb; if ( is_search() ) { return "DISTINCT"; } return $where; } add_filter( 'posts_distinct', 'prevent_duplicates' );
Zobaczmy teraz, co dzieje się w interfejsie użytkownika, jeśli wyszukamy ciąg „wordpress.org”.

Zgodnie z oczekiwaniami tym razem wyniki są prawidłowe. Wyszukiwarka WordPress znalazła jako wynik „post 1”, ponieważ zawiera pole „źródło” o wartości „https://dev. wordpress.org /reference/functions/add_post_meta/
Niestandardowe typy postów w wynikach wyszukiwania WordPress
Inną rzeczą, którą możesz chcieć zrobić, jest umożliwienie przeszukiwania niestandardowych typów postów (jeśli nie masz pewności, jak utworzyć niestandardowy typ postów, zapoznaj się z naszymi artykułami na ten temat tutaj).
Wyobraźmy sobie, że stworzyliśmy niestandardowy typ posta o nazwie „książki” i chcemy, aby ten typ posta pojawiał się w wynikach wyszukiwania. Tym razem nie musimy ponownie tworzyć zapytania SQL, a jedynie ponownie zdefiniować typy postów w haku pre_get_posts
, jak pokazano poniżej. Kod należy ponownie umieścić w pliku functions.php
.
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' );
To, co tutaj zrobiliśmy, to dodanie żądanych typów postów, które mają być uwzględnione w wynikach wyszukiwania jako argumenty do haka post_type
.
Jeśli chcesz wykluczyć typ, po prostu usuń go z tablicy.
Wniosek
Poprawa wyszukiwania w witrynie WordPress może być naprawdę pomocna i ogromnie zaoszczędzić czas. Dla użytkownika końcowego ważne jest również, aby mógł wyszukiwać zarówno niestandardowe typy postów, jak i niestandardowe pola. Mam nadzieję, że powyższa instrukcja dała ci wgląd w to, jak osiągnąć to na własnej stronie internetowej.