Tworzenie widżetu wyszukiwania za pomocą WordPress REST API
Opublikowany: 2016-03-28Programiści WordPress będą świadomi, że REST API istnieje już od jakiegoś czasu, ale pod koniec zeszłego roku został zintegrowany z rdzeniem, co oznacza, że można go teraz wykorzystywać w widżetach i wtyczkach.
W tym artykule zbudujemy prosty widżet wyszukiwania z różnicą. Korzystając z interfejsu API REST WordPress, ten widżet przeszuka zewnętrzną witrynę WordPress i wyświetli wyniki w widżecie.
Ten post jest kontynuacją mojego ostatniego na Co musisz wiedzieć o WordPress REST API
Zbuduj bazę wiedzy z możliwością wyszukiwania i pomóż swoim klientom pomóc sobie.
Pobierz wtyczkęBudowanie wtyczki widżetu
Podobnie jak w poprzednim artykule, zakłada się podstawową wiedzę na temat budowania wtyczek i widżetów. Jeśli nie masz pewności, na końcu tego artykułu znajduje się sugerowana lektura.
Rzućmy okiem na istniejącą wtyczkę, którą stworzyliśmy w poprzednim artykule. Twój kod powinien wyglądać mniej więcej tak:
/**
* Plugin Name: KB - REST API Widget
* Author: Kirsty Burgoine
*/
class REST_API_Widget extends WP_Widget {
/**
* Sets up the widgets name etc
*/
public function __construct() {
$widget_ops = array(
'classname' => 'rest-api-widget',
'description' => 'A REST API widget that pulls posts from a different website'
);
parent::__construct( 'rest_api_widget', 'REST API Widget', $widget_ops );
}
/**
* Outputs the content of the widget
*
* @param array $args
* @param array $instance
*/
public function widget( $args, $instance ) {
// outputs the content of the widget
$response = wp_remote_get( 'http://website-with-api.com/wp-json/wp/v2 /ht_kb/' );
if( is_wp_error( $response ) ) {
return;
}
$posts = json_decode( wp_remote_retrieve_body( $response ) );
if( empty( $posts ) ) {
return;
}
echo $args['before_widget'];
if( !empty( $instance['title'] ) ) {
echo $args['before_title'] . apply_filters( 'widget_title', $instance['title'], $instance, $this->id_base ) . $args['after_title'];
}
// Main Widget Content Here
if( !empty( $posts ) ) {
echo '<ul>';
foreach( $posts as $post ) {
echo '<li><a href="' . $post->link. '">' . $post->title->rendered . '</a></li>';
}
echo '</ul>';
}
echo $args['after_widget'];
}
/**
* Outputs the options form on admin
*
* @param array $instance The widget options
*/
public function form( $instance ) {
//outputs the options form on admin
$title = ( !empty( $instance['title'] ) ) ? $instance['title'] : '';
?>
<label for="<?php echo $this->get_field_name( 'title' ); ?>">Title: </label>
<input class="widefat" id="<?php echo $this->get_field_id( 'title' ); ?>" name="<?php echo $this->get_field_name( 'title' ); ?>" type="text" value="<?php echo esc_attr( $title ); ?>" />
<?php
}
}//end class
add_action( 'widgets_init', function(){
register_widget( 'REST_API_Widget' );
});
Zasadniczo stworzyliśmy nową wtyczkę. W tej wtyczce stworzyliśmy widżet, który wyświetla listę niestandardowych postów z bazy heroicznej wiedzy z innej strony internetowej.
To, co zamierzamy teraz zrobić, to zmienić to, aby utworzyć również funkcję wyszukiwania.
Krok 1: Zmiana podstawowego zapytania, aby uzyskać inne wyniki
W ostatnim artykule, który pamiętasz, omawialiśmy, jak POBRAĆ listę postów, a następnie zmienić parametry, abyśmy mogli zamiast tego uzyskać niestandardowy typ postu z bazy wiedzy.
Cóż, może nie jest to zaskakujące, ale to nie wszystko, co możemy zrobić z metodą GET. Używając parametrów filtrowania możemy faktycznie użyć dowolnego z argumentów dostępnych podczas wywoływania WP_Query. Na przykład, gdybyśmy chcieli zmienić liczbę wyświetlanych postów, moglibyśmy dodać:
/posts?filter[posts_per_page]=5
Wykonywanie zdalnego połączenia mniej więcej tak:
$response = wp_remote_get( 'http://website-with -api.com.com/wp-json/wp/v2/posts?filter[posts_per_page]=5' );
Lub, gdybyśmy chcieli wyświetlić tylko jeden losowy post, moglibyśmy dodać:
/posts?filter[orderby]=rand&amp;filter[posts_per_page]=1
To samo dotyczy parametru wyszukiwania. W standardowym zapytaniu WP parametr wyglądałby tak:
's' => 'keyword'
Dlatego nasza zdalna rozmowa musi wyglądać tak:
$response = wp_remote_get( 'http://website-with -api.com.com/wp-json/wp/v2/posts?filter[s]=keyword');
Jest to dość proste, gdy już opanujesz konwersję parametrów z WP_Query na ciąg URL interfejsu API.
Aby uzyskać szczegółowe informacje na temat dostępnych parametrów, zobacz przewodnik po kodeksie WP_Query.
W rzeczywistości nie chcemy przeszukiwać standardowych postów, chcemy przeszukiwać niestandardowy typ postu w bazie wiedzy. Jednak, jak widzieliśmy w poprzednim artykule, jest to łatwe, ponieważ udostępniliśmy publicznie nasz niestandardowy typ posta, dodając filtr. Dlatego wszystko, co musimy tutaj zrobić, to wysłać zapytanie do niestandardowego typu postu bazy wiedzy, zamieniając /posts/ z nazwą niestandardowego typu postu. W tym przypadku /ht_kb/ . Połączenie zdalne będzie teraz wyglądać tak:
$response = wp_remote_get( 'http://website-with-api.com/wp-json/wp/v2/ht_kb?filter[s]=keyword' );
Krok 2: Pole wyszukiwania i dostosowywanie wyników
Więc teraz przyjrzeliśmy się zmianie zapytania w celu filtrowania według danego wyszukiwanego hasła, następnym krokiem jest stworzenie sposobu na uzyskanie tego wyszukiwanego hasła.
Po pierwsze, musimy dodać pole wyszukiwania do wtyczki. Ponieważ będzie to tylko prosty formularz wyszukiwania, możemy użyć funkcji get_search_form() już skonfigurowanej przez WordPress zamiast tworzyć oddzielny formularz wyszukiwania.
W pliku wtyczki poszukaj linii z komentarzem // Main Widget Content Tutaj w funkcji widżetu i dodaj get_search_form(); i edytuj bezpośrednio pod nim, aby wyglądało to tak:
// Main Widget Content Here
get_search_form();
if( !empty( $posts ) ) {
echo '<ul>';
foreach( $posts as $post ) {
echo '<li><a href="' . $post->link. '">' . $post->title->rendered . '</a></li>';
}
echo '</ul>';
}
Teraz, gdy przeglądamy widżet na stronie, zobaczysz standardowy formularz wyszukiwania i pod nim listę postów z Bazy wiedzy.

Wiemy z używania get_search_form(); że kiedy czegoś szukamy, parametr wyszukiwania pojawia się w adresie URL w następujący sposób:
/?s=test
„s” to parametr $_GET, a „test” to wyszukiwane hasło. Dlatego pozostaje tylko pobrać wyszukiwane hasło z adresu URL i użyć go w odpowiedzi w następujący sposób:
if ( isset ( $_GET['s'] ) && !empty( $_GET['s'] ) ) {
$response = wp_remote_get( 'http://website-with-api.com/wp-json/wp/v2/ht_kb?filter[s]='.$_GET['s'] );
}
else {
$response = wp_remote_get( 'http://website-with-api.com/wp-json/wp/v2/ht_kb/' );
}
To, co robi ten kod, to sprawdzenie, czy $_GET['s'] zostało ustawione i nie jest puste. Jeśli tak jest/jest, należy to uwzględnić w odpowiedzi. Jeśli nie, oznacza to, że wyszukiwanie nie jest wykonywane i chcesz wyświetlać wszystkie posty bazy wiedzy w normalny sposób.
Więcej szczegółów na temat funkcji get_search_form() można znaleźć tutaj.
To jest miejsce, w którym spodziewalibyśmy się, że ten artykuł się skończy, prawda? W końcu skonfigurowaliśmy formularz wyszukiwania, który przeszukuje posty na zewnętrznej stronie internetowej za pomocą interfejsu API REST WordPress, a następnie zwraca te wyniki na podstawie parametru wyszukiwania. Jednakże…
Krok 3: Zmiana wyświetlanych wyników
Jeśli przetestujemy nowy widżet wyszukiwania, zobaczymy, że widżet działa zgodnie z oczekiwaniami, jednak zwróci również wyniki z bieżącej witryny w treści strony głównej.

Wynika to z systemu szablonów WordPress. WordPress używa ciągu zapytania, aby określić, którego szablonu lub zestawu szablonów użyć. Ponieważ po przesłaniu formularza wyszukiwania dodaje on parametr „s” do adresu URL, co oznacza, że WordPress ma przeprowadzić wyszukiwanie i przekierować do strony wyników wyszukiwania. Który w motywie TwentySixteen to search.php.

Więcej informacji można znaleźć w dokumentacji hierarchii szablonów.
To świetnie, gdybyśmy chcieli przeprowadzić wyszukiwanie na lokalnej stronie internetowej i zewnętrznej przy użyciu API w tym samym czasie, ponieważ wyświetlane są wyniki dla obu. Jednak w tym przypadku nie chcemy tego robić. Chcemy, aby w widgecie wyświetlały się tylko wyniki zwrócone za pomocą interfejsu API. Strona główna powinna pozostać nienaruszona.
Można to zrobić na kilka sposobów. W tym przykładzie przyjrzymy się, jak zmienić metodę get_search_form(); funkcja, aby nie używać już „s” jako parametru wyszukiwania. Zamiast tego zostanie zmieniony na „a”, aby ominąć problem.
Pierwszym krokiem jest faktyczne zmodyfikowanie formularza poprzez utworzenie nowej funkcji.
function api_search_form( $form ) {
$form = '<form role="search" method="get" class="search-form" action="' . home_url( '/' ) . '">
<label>
<span class="screen-reader-text">' . _x( 'Search for:', 'label' ) . '</span>
<input type="search" class="search-field" placeholder="' . esc_attr_x( 'Search …', 'placeholder' ) .'" value="' . get_search_query() . '" name="a" title="' . esc_attr_x( 'Search for:', 'label' ) .'" />
</label>
<button type="submit" class="search-submit"><span class="screen-reader-text">Search</span></button>
</form>';
return $form;
}
add_filter( 'get_search_form', 'api_search_form', 100 );
Sama funkcja jest dość prosta, w zasadzie jest to nowa forma do użycia zamiast formy domyślnej. Jeśli spojrzymy na motyw referencyjny TwentySixteen i sprawdzimy istniejący formularz wyszukiwania, zauważymy, że jedyną różnicą w kodzie jest nazwa danych wejściowych wyszukiwania. Pierwotnie było to 'name=s', a teraz jest to 'name=a'. Spowoduje to usunięcie parametru „s” z adresu URL.
Uwaga: w tym podejściu modyfikujemy główny formularz wyszukiwania, aby wyszukiwał za pomocą interfejsu API zamiast przeszukiwać witrynę hosta. Dlatego ważne jest, aby wziąć pod uwagę, że jeśli użyjemy głównego formularza wyszukiwania w dowolnym innym miejscu witryny, nie będzie on już przekierowywał wyników wyszukiwania z witryny hosta. Aby mieć dwa różne wyszukiwania, najłatwiejszym rozwiązaniem byłoby dodanie kodu dla tego nowego formularza bezpośrednio do widżetu zamiast modyfikowania get_search_form();
Ostatnim krokiem jest dodanie filtra. To każe WordPressowi zastąpić istniejący formularz tym. Możemy wkleić cały blok kodu do pliku wtyczki po klasie widżetu. Może to być dołączone do pliku functions.php motywu, ale dołączając go do wtyczki, oznacza to, że zmiana formularza jest dokonywana tylko wtedy, gdy wtyczka jest aktywowana.
Teraz, gdy zmieniliśmy nazwę danych wejściowych na „a”, musimy zmienić również rzeczywisty parametr wyszukiwania. Parametr pojawi się teraz w adresie URL jako: /?a=test, zamiast /?s=test, a tym samym usunie część ciągu zapytania, która mówi WordPressowi, że powinno to przekierować do szablonu wyników wyszukiwania.
Abyś mógł wyszukiwać przy użyciu nowego parametru, zaktualizuj kod napisany wcześniej dla wywołań zdalnych, tak aby używał parametru „a” zamiast „s”.
Powinien teraz wyglądać tak:
if ( isset ( $_GET['a'] ) && !empty( $_GET['a'] ) ) {
$response = wp_remote_get( 'http://website-with-api.com/wp-json/wp/v2/ht_kb?filter[s]='.$_GET['a'] );
} else {
$response = wp_remote_get( 'http://website-with-api.com/wp-json/wp/v2/ht_kb/' );
}
Zauważ, że chociaż parametr wyszukiwania w $_GET uległ zmianie, nie zmienia to filtra w rzeczywistym zapytaniu. Dzieje się tak, ponieważ standardowe zapytanie WP dotyczące wyszukiwania to nadal „s”.
Teraz, gdy testujemy widżet, powinniśmy być w stanie przeszukiwać artykuły z bazy wiedzy w zewnętrznej witrynie internetowej i zwracać wyniki bez przekierowywania na stronę wyników wyszukiwania.

Pełny kod widżetu wygląda tak:
/**
* Plugin Name: KB - REST API Widget
* Author: Kirsty Burgoine
*/
class REST_API_Widget extends WP_Widget {
/**
* Sets up the widgets name etc
*/
public function __construct() {
$widget_ops = array(
'classname' => 'rest-api-widget',
'description' => 'A REST API widget that pulls posts from a different website');
parent::__construct( 'rest_api_widget', 'REST API Widget', $widget_ops );
}
/**
* Outputs the content of the widget
*
* @param array $args
* @param array $instance
*/
public function widget( $args, $instance ) {
// outputs the content of the widget
if ( isset ( $_GET['a'] ) && !empty( $_GET['a'] ) ) {
$response = wp_remote_get( 'http://website-with-api.com/wp-json/wp/v2/ht_kb?filter[s]='.$_GET['a'] );
} else {
$response = wp_remote_get( 'http://website-with-api.com/wp-json/wp/v2/ht_kb/' );
}
if( is_wp_error( $response ) ) {
return;
}
$posts = json_decode( wp_remote_retrieve_body( $response ) );
if( empty( $posts ) ) {
return;
}
echo $args['before_widget'];
if( !empty( $instance['title'] ) ) {
echo $args['before_title'] . apply_filters( 'widget_title', $instance['title'], $instance, $this->id_base ) . $args['after_title'];
}
// Main Widget Content Here
get_search_form();
if( !empty( $posts ) ) {
echo '<ul>';
foreach( $posts as $post ) {
echo '<li><a href="' . $post->link. '">' . $post->title->rendered . '</a></li>';
}
echo '</ul>';
}
echo $args['after_widget'];
}
/**
* Outputs the options form on admin
*
* @param array $instance The widget options
*/
public function form( $instance ) {
// outputs the options form on admin
$title = ( !empty( $instance['title'] ) ) ? $instance['title'] : '';
?>
<label for="<?php echo $this->get_field_name( 'title' ); ?>">Title: </label>
<input class="widefat" id="<?php echo $this->get_field_id( 'title' ); ?>"
name="<?php echo $this->get_field_name( 'title' ); ?>" type="text" value="<?php echo esc_attr( $title ); ?>" />
<?php
}
}
function api_search_form( $form ) {
$form = '<form role="search" method="get" class="search-form" action="' . home_url( '/' ) . '">
<label>
<span class="screen-reader-text">' . _x( 'Search for:', 'label' ) . '</span>
<input type="search" class="search-field" placeholder="' . esc_attr_x( 'Search …', 'placeholder' ) .'" value="' . get_search_query() . '" name="a" title="' . esc_attr_x( 'Search for:', 'label' ) .'" />
</label>
<button type="submit" class="search-submit"><span class="screen-reader-text">Search</span></button>
</form>';
return $form;
}
add_filter( 'get_search_form', 'api_search_form', 100 );
add_action( 'widgets_init', function(){
register_widget( 'REST_API_Widget' );
});
Jest to bardzo prosta implementacja niestandardowego widżetu wyszukiwania przy użyciu interfejsu API REST. Jak pokazano wcześniej, możemy dodać do zapytania dodatkowe filtry, aby ograniczyć liczbę wyników wyszukiwania lub kolejność ich wyświetlania. Możesz wybrać wyświetlanie dodatkowych informacji w widżecie, takich jak wyszukiwane hasło i liczba wyników, lub znając jQuery/JavaScript możesz pójść dalej i dodać fajny efekt AJAX, aby wyniki były zwracane bez konieczności odświeżania strony.
Dalsza lektura:
- Widgety API (Kodeks WordPress)
- Wprowadzenie do tworzenia pierwszego widgetu WordPress (Tutsplus)
- Jak stworzyć niestandardowy widget WordPress (WP Beginner)
- Jak stworzyć wtyczkę widżetu dla WordPress (WP Explorer)
