Creazione di un widget di ricerca utilizzando l'API REST di WordPress
Pubblicato: 2016-03-28Gli sviluppatori di WordPress sapranno che l'API REST è in circolazione da un po' di tempo, ma alla fine dell'anno scorso è stata integrata nel core, il che significa che ora può essere sfruttata in widget e plug-in.
In questo articolo creeremo un semplice widget di ricerca con una differenza. Utilizzando l'API REST di WordPress, questo widget cercherà un sito Web WordPress esterno e visualizzerà i risultati nel widget.
Questo post continua dal mio ultimo su Cosa devi sapere sull'API REST di WordPress
Costruisci una base di conoscenze ricercabile e aiuta i tuoi clienti ad aiutare se stessi.
Ottieni il plug-inCostruire il plugin del widget
Come nell'articolo precedente, si presuppone una conoscenza di base della creazione di plugin e widget. Se non sei sicuro, c'è qualche lettura suggerita per te alla fine di questo articolo.
Diamo un'occhiata al plugin esistente che abbiamo creato nell'ultimo articolo. Il tuo codice dovrebbe assomigliare a questo:
/**
* 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' );
});
In sostanza, abbiamo creato un nuovo plugin. In quel plugin abbiamo creato un widget che mostra un elenco di post personalizzati dalla base di conoscenze eroiche da un altro sito web.
Quello che faremo ora è modificare questo per creare anche una funzione di ricerca.
Passaggio 1: modifica della query di base per ottenere risultati diversi
Nell'ultimo articolo ricorderete che abbiamo discusso di come OTTENERE un elenco di post e quindi di come modificare i parametri in modo da poter ottenere invece il tipo di post personalizzato della knowledge base.
Bene, potrebbe non essere così sorprendente da imparare, non è tutto ciò che possiamo fare con il metodo GET. Utilizzando i parametri di filtraggio possiamo effettivamente utilizzare uno qualsiasi degli argomenti disponibili quando chiamiamo WP_Query. Ad esempio, se volessimo modificare il numero di post visualizzati potresti aggiungere:
/posts?filter[posts_per_page]=5
Effettuare la chiamata remota in questo modo:
$response = wp_remote_get( 'http://website-with -api.com.com/wp-json/wp/v2/posts?filter[posts_per_page]=5' );
Oppure, se volessimo visualizzare solo un post casuale, potremmo aggiungere:
/posts?filter[orderby]=rand&amp;filter[posts_per_page]=1
E questo è lo stesso per un parametro di ricerca. In una query WP standard, il parametro sarebbe simile a questo:
's' => 'keyword'
Pertanto, la nostra chiamata remota deve essere simile a questa:
$response = wp_remote_get( 'http://website-with -api.com.com/wp-json/wp/v2/posts?filter[s]=keyword');
È abbastanza semplice una volta che hai la testa sulla conversione dei parametri da WP_Query nella stringa URL dell'API.
Per i dettagli completi su quali parametri sono disponibili, vedere la guida al codex WP_Query.
Tuttavia, in realtà non vogliamo cercare post standard, vogliamo cercare il tipo di post personalizzato della knowledge base. Tuttavia, come abbiamo visto nell'articolo precedente, questo è facile perché abbiamo reso pubblicamente disponibile il nostro tipo di post personalizzato aggiungendo un filtro. Pertanto, tutto ciò che dobbiamo fare qui è interrogare il tipo di post personalizzato della knowledge base scambiando /posts/ con il nome del tipo di post personalizzato. In questo caso /ht_kb/ . La chiamata remota sarà ora simile a questa:
$response = wp_remote_get( 'http://website-with-api.com/wp-json/wp/v2/ht_kb?filter[s]=keyword' );
Passaggio 2: la casella di ricerca e la personalizzazione dei risultati
Quindi ora abbiamo esaminato la modifica della query per filtrare in base a un determinato termine di ricerca, il passaggio successivo è creare un modo per ottenere quel termine di ricerca.
Innanzitutto, dobbiamo aggiungere una casella di ricerca al plug-in. Poiché questo sarà solo un semplice modulo di ricerca, possiamo utilizzare la funzione get_search_form() già impostata da WordPress invece di creare un modulo di ricerca separato.
Nel file del plugin, cerca la riga con il commento // Main Widget Content Qui all'interno della tua funzione widget e aggiungi get_search_form(); e modificalo direttamente sotto di esso in modo che assomigli a questo:
// 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>';
}
Ora, quando visualizziamo il widget sulla pagina, vedrai il modulo di ricerca standard e l'elenco dei post della Knowledge Base al di sotto di esso.

Sappiamo dall'utilizzo di get_search_form(); che quando cerchiamo qualcosa, il parametro di ricerca appare nell'url in questo modo:
/?s=test
's' è il parametro $_GET e 'test' è il termine di ricerca. Pertanto, tutto ciò che resta è prendere il termine di ricerca dall'URL e usarlo nella risposta in questo modo:
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/' );
}
Quello che fa questo codice è controllare se $_GET['s'] è stato impostato e non è vuoto. Se lo è/è, includilo nella tua risposta. In caso contrario, la ricerca non viene eseguita e si desidera visualizzare tutti i post della knowledge base come di consueto.
Maggiori dettagli sulla funzione get_search_form() possono essere trovati qui.
È qui che ci aspetteremmo che questo articolo finisse, giusto? Dopotutto, abbiamo impostato un modulo di ricerca che interroga i post su un sito Web esterno utilizzando l'API REST di WordPress e quindi restituisce quei risultati in base al parametro di ricerca. Tuttavia…
Passaggio 3: modifica dei risultati visualizzati
Se testiamo il nuovo widget di ricerca, possiamo vedere che il widget funziona come previsto, tuttavia, restituirà anche i risultati del sito Web corrente nel contenuto della pagina principale.

Ciò è dovuto al sistema di modelli di WordPress. WordPress utilizza la stringa di query per determinare quale modello o set di modelli utilizzare. Perché, quando il modulo di ricerca viene inviato, aggiunge il parametro "s" all'URL, sta dicendo a WordPress di eseguire una ricerca e reindirizzare alla pagina dei risultati della ricerca. Che, nel tema TwentySixteen è search.php.

Per ulteriori informazioni, fare riferimento alla documentazione della gerarchia dei modelli.
È fantastico se volessimo eseguire la ricerca su un sito Web locale e su un sito Web esterno utilizzando l'API contemporaneamente perché vengono visualizzati i risultati per entrambi. Tuttavia, in questo caso non vogliamo farlo. Vogliamo solo che i risultati restituiti utilizzando l'API vengano visualizzati nel widget. La pagina principale dovrebbe rimanere inalterata.
Ci sono diversi modi per farlo. Per questo esempio, vedremo come modificare get_search_form(); funzione per non utilizzare più 's' come parametro di ricerca. Invece verrà cambiato in "a" per aggirare il problema.
Il primo passaggio consiste nel modificare effettivamente il modulo creando una nuova funzione.
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 );
La funzione stessa è piuttosto semplice, è fondamentalmente un nuovo modulo da utilizzare al posto del modulo predefinito. Se osserviamo il tema di riferimento TwentySixteen e ispezioniamo il modulo di ricerca esistente, notiamo che l'unica differenza nel codice è il nome dell'input di ricerca. Originariamente era 'nome=s' e ora è 'nome=a'. Questo rimuove il parametro 's' dall'URL.
Nota: con questo approccio, modifichiamo il modulo di ricerca principale per eseguire la ricerca utilizzando l'API invece di cercare nel sito Web host. Pertanto, è importante considerare che se utilizziamo il modulo di ricerca principale in qualsiasi altra parte del sito Web, non verrà più reindirizzato ai risultati della ricerca dal sito Web host. Per avere due ricerche diverse, la soluzione più semplice sarebbe aggiungere il codice per questo nuovo modulo direttamente nel widget invece di modificare get_search_form();
L'ultimo passaggio consiste nell'aggiungere il filtro. Questo dice a WordPress di sostituire il modulo esistente con questo invece. Possiamo incollare l'intero blocco di codice nel file del plugin dopo la classe del widget. Questo potrebbe invece essere incluso nel functions.php del tema, ma includendolo nel plugin, significa che la modifica al modulo viene effettuata solo se il plugin è attivato.
Ora che abbiamo cambiato il nome dell'input in 'a', dobbiamo cambiare anche il parametro di ricerca effettivo. Il parametro ora apparirà nell'url come: /?a=test, invece di /?s=test e quindi rimuovendo la parte della stringa di query che dice a WordPress che questo dovrebbe reindirizzare al modello dei risultati della ricerca.
In modo da poter eseguire la ricerca utilizzando il nuovo parametro, aggiornare il codice scritto in precedenza per la chiamata remota per utilizzare il parametro 'a' invece di 's'.
Ora dovrebbe assomigliare a questo:
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/' );
}
Si noti che sebbene il parametro di ricerca in $_GET sia cambiato, ciò non cambia il filtro nella query effettiva. Questo perché la query WP standard per la ricerca è ancora "s".
Ora, quando testiamo il widget, dovremmo essere in grado di cercare gli articoli della Knowledge Base sul tuo sito Web esterno e restituire i risultati senza essere reindirizzati a una pagina dei risultati di ricerca.

Il codice completo per il widget è simile al seguente:
/**
* 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' );
});
Questa è un'implementazione molto semplice di un widget di ricerca personalizzato che utilizza l'API REST. Come illustrato in precedenza, potremmo aggiungere filtri aggiuntivi alla query per limitare il numero di risultati di ricerca o l'ordine in cui vengono visualizzati. Puoi scegliere di visualizzare informazioni aggiuntive nel widget come il termine di ricerca e il numero di risultati, oppure, se conosci jQuery / Javascript potresti andare oltre e aggiungere un bell'effetto AJAX in modo che i risultati vengano restituiti senza la necessità di aggiornare la pagina.
Ulteriori letture:
- Widget API (codice WordPress)
- Introduzione alla creazione del tuo primo widget WordPress (Tutsplus)
- Come creare un widget WordPress personalizzato (WP Beginner)
- Come creare un plugin per widget per WordPress (WP Explorer)
