Crearea unui widget de căutare folosind API-ul REST WordPress
Publicat: 2016-03-28Dezvoltatorii WordPress vor ști că API-ul REST există de ceva timp, dar la sfârșitul anului trecut a fost integrat în core, ceea ce înseamnă că poate fi acum utilizat în widget-uri și plugin-uri.
În acest articol vom construi un widget de căutare simplu cu o diferență. Folosind API-ul WordPress REST, acest widget va căuta un site web extern WordPress și va afișa rezultatele în widget.
Această postare continuă de la ultima mea despre Ce trebuie să știți despre API-ul REST WordPress
Construiește o bază de cunoștințe care poate fi căutată și ajută-ți clienții să se ajute singuri.
Obțineți pluginulConstruirea plugin-ului widget
Ca și în articolul precedent, se presupun câteva cunoștințe de bază despre crearea de pluginuri și widget-uri. Dacă nu sunteți sigur, există câteva lecturi sugerate pentru dvs. la sfârșitul acestui articol.
Să aruncăm o privire la pluginul existent pe care l-am creat în ultimul articol. Codul dvs. ar trebui să arate cam așa:
/**
* 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' );
});
În esență, am creat un nou plugin. În acel plugin, am creat un widget care afișează o listă de postări personalizate din baza de cunoștințe eroice de pe un alt site web.
Ceea ce vom face acum este să modificăm acest lucru pentru a crea și o funcție de căutare.
Pasul 1: Modificarea interogării de bază pentru a obține rezultate diferite
În ultimul articol vă veți aminti că am discutat despre cum să OBȚIȚI o listă de postări și apoi cum să schimbăm parametrii, astfel încât să putem obține tipul de postare personalizat din baza de cunoștințe.
Ei bine, s-ar putea să nu fie atât de surprinzător să învățăm, asta nu este tot ce putem face cu metoda GET. Folosind parametrii de filtrare, putem folosi de fapt oricare dintre argumentele disponibile atunci când apelăm WP_Query. De exemplu, dacă dorim să schimbăm numărul de postări afișate, puteți adăuga:
/posts?filter[posts_per_page]=5
Efectuarea apelului de la distanță cam așa:
$response = wp_remote_get( 'http://website-with -api.com.com/wp-json/wp/v2/posts?filter[posts_per_page]=5' );
Sau, dacă dorim să afișăm o singură postare aleatorie, am putea adăuga:
/posts?filter[orderby]=rand&amp;filter[posts_per_page]=1
Și acest lucru este același pentru un parametru de căutare. Într-o interogare WP standard, parametrul ar arăta astfel:
's' => 'keyword'
Prin urmare, apelul nostru de la distanță trebuie să arate astfel:
$response = wp_remote_get( 'http://website-with -api.com.com/wp-json/wp/v2/posts?filter[s]=keyword');
Este destul de simplu odată ce vă pricepeți la conversia parametrilor din WP_Query în șirul URL API.
Pentru detalii complete despre parametrii disponibili, consultați ghidul de codex WP_Query.
De fapt, nu vrem să căutăm postări standard, vrem să căutăm tipul de postare personalizată din baza de cunoștințe. Cu toate acestea, așa cum am văzut în articolul anterior, acest lucru este ușor de făcut, deoarece am făcut public tipul nostru personalizat de postare prin adăugarea unui filtru. Prin urmare, tot ce trebuie să facem aici este să interogăm tipul de postare personalizată din baza de cunoștințe schimbând /posturi/ cu numele tipului de postare personalizată. În acest caz /ht_kb/ . Apelul de la distanță va arăta acum astfel:
$response = wp_remote_get( 'http://website-with-api.com/wp-json/wp/v2/ht_kb?filter[s]=keyword' );
Pasul 2: caseta de căutare și rezultatele personalizării
Deci, acum ne-am uitat la modificarea interogării pentru a filtra după un anumit termen de căutare, următorul pas este să creăm o modalitate de a obține acel termen de căutare.
În primul rând, trebuie să adăugăm o casetă de căutare la plugin. Deoarece acesta va fi doar un simplu formular de căutare, putem folosi funcția get_search_form() deja configurată de WordPress în loc să creăm un formular de căutare separat.
În fișierul plugin, căutați linia cu comentariul // Main Widget Content Aici în interiorul funcției widget și adăugați get_search_form(); și editați direct sub acesta, astfel încât să arate așa:
// 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>';
}
Acum, când vedem widgetul pe pagină, veți vedea formularul de căutare standard și lista de postări din baza de cunoștințe dedesubt.

Știm din utilizarea get_search_form(); că atunci când căutăm ceva, parametrul de căutare apare în url astfel:
/?s=test
„s” fiind parametrul $_GET și „test” fiind termenul de căutare. Prin urmare, tot ce rămâne este să luați termenul de căutare din URL și să-l utilizați în răspuns astfel:
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/' );
}
Ceea ce face acest cod este să verifice dacă $_GET['s'] a fost setat și nu este gol. Dacă are/este, atunci îl includeți în răspunsul dvs. Dacă nu, atunci o căutare nu este efectuată și doriți să afișați toate postările din baza de cunoștințe ca de obicei.
Mai multe detalii despre funcția get_search_form() pot fi găsite aici.
Aici ne-am aștepta să se termine acest articol, nu? La urma urmei, am configurat un formular de căutare care interogează postările de pe un site web extern folosind API-ul REST WordPress și apoi a returnat acele rezultate pe baza parametrului de căutare. In orice caz…
Pasul 3: Modificarea rezultatelor afișate
Dacă testăm noul widget de căutare, putem vedea că widgetul funcționează conform așteptărilor, totuși, va returna și rezultate de pe site-ul actual în conținutul paginii principale.

Acest lucru se datorează sistemului de șabloane WordPress. WordPress folosește șirul de interogare pentru a determina ce șablon sau set de șabloane să folosească. Deoarece, atunci când formularul de căutare este trimis, acesta adaugă parametrul „s” la adresa URL, îi spune WordPress să efectueze o căutare și să redirecționeze către pagina cu rezultatele căutării. Care, în tema TwentySixteen este search.php.

Pentru mai multe informații, consultați documentația ierarhiei șablonului.
Este grozav dacă dorim să efectuăm căutarea pe un site web local și pe un site web extern folosind API-ul în același timp, deoarece rezultatele pentru ambele sunt afișate. Cu toate acestea, în acest caz, nu vrem să facem asta. Vrem doar ca rezultatele returnate folosind API să fie afișate în widget. Pagina principală ar trebui să rămână neafectată.
Există o serie de moduri de a face acest lucru. Pentru acest exemplu, ne vom uita la cum să modificăm get_search_form(); funcția să nu mai folosească „s” ca parametru de căutare. În schimb, va fi schimbat în „a” pentru a ocoli problema.
Primul pas este modificarea efectivă a formularului prin crearea unei noi funcții.
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 );
Funcția în sine este destul de simplă, practic este o formă nouă de utilizat în locul formularului implicit. Dacă ne uităm la tema de referință TwentySixteen și inspectăm formularul de căutare existent, observăm că singura diferență a codului este numele intrării de căutare. Inițial era „name=s”, iar acum este „name=a”. Aceasta elimină parametrul „s” din URL.
Notă: Cu această abordare, modificăm formularul principal de căutare pentru a căuta folosind API-ul în loc să căutăm pe site-ul gazdă. Prin urmare, este important să luăm în considerare că, dacă folosim formularul principal de căutare oriunde altundeva pe site, acesta nu va mai redirecționa către rezultatele căutării de pe site-ul web gazdă. Pentru a avea două căutări diferite, atunci cea mai ușoară soluție ar fi să adăugați codul pentru acest nou formular direct în widget în loc să modificați get_search_form();
Ultimul pas este adăugarea filtrului. Aceasta îi spune WordPress să înlocuiască formularul existent cu acesta. Putem lipi întregul bloc de cod în fișierul plugin după clasa de widget. Acesta ar putea fi inclus în schimb funcțiile.php al temei, dar prin includerea acestuia în plugin, înseamnă că modificarea formularului se face doar dacă pluginul este activat.
Acum că am schimbat numele intrării în „a”, trebuie să schimbăm și care va fi parametrul de căutare real. Parametrul va apărea acum în url ca: /?a=test, în loc de /?s=test și, prin urmare, elimină partea din șirul de interogare care îi spune WordPress că aceasta ar trebui să redirecționeze către șablonul de rezultate ale căutării.
Pentru a putea căuta folosind noul parametru, actualizați codul scris anterior pentru apelul la distanță pentru a utiliza parametrul „a” în loc de „s”.
Acum ar trebui să arate așa:
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/' );
}
Observați că, deși parametrul de căutare din $_GET s-a modificat, acest lucru nu modifică filtrul din interogarea reală. Acest lucru se datorează faptului că interogarea WP standard pentru căutare este încă „s”.
Acum, când testăm widgetul, ar trebui să putem căuta articolele din baza de cunoștințe pe site-ul dvs. extern și să returnăm rezultatele fără a fi redirecționați către o pagină cu rezultate ale căutării.

Codul complet pentru widget arată astfel:
/**
* 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' );
});
Aceasta este o implementare foarte simplă a unui widget de căutare personalizat folosind API-ul REST. După cum sa ilustrat mai devreme, am putea adăuga filtre suplimentare la interogare pentru a limita numărul de rezultate ale căutării sau ordinea în care sunt afișate. Puteți alege să afișați informații suplimentare în widget, cum ar fi termenul de căutare și numărul de rezultate sau, dacă cunoașteți jQuery/Javascript, puteți continua acest lucru și adăugați un efect AJAX frumos, astfel încât rezultatele să fie returnate fără a fi nevoie să reîmprospătați pagina.
Lectură suplimentară:
- API Widgets (WordPress Codex)
- Introducere în crearea primului widget WordPress (Tutsplus)
- Cum să creați un widget WordPress personalizat (WP Beginner)
- Cum se creează un plugin widget pentru WordPress (WP Explorer)
