Création d'un widget de recherche à l'aide de l'API WordPress REST
Publié: 2016-03-28Les développeurs WordPress savent que l'API REST existe depuis un certain temps, mais à la fin de l'année dernière, elle a été intégrée au noyau, ce qui signifie qu'elle peut désormais être exploitée dans les widgets et les plugins.
Dans cet article, nous allons créer un widget de recherche simple avec une différence. À l'aide de l'API WordPress REST, ce widget recherchera un site Web WordPress externe et affichera les résultats dans le widget.
Ce post continue de mon dernier sur Ce que vous devez savoir sur l'API WordPress REST
Créez une base de connaissances consultable et aidez vos clients à s'aider eux-mêmes.
Obtenir le plug-inConstruire le plugin widget
Comme dans l'article précédent, certaines connaissances de base sur la création de plugins et de widgets sont supposées. Si vous n'êtes pas sûr, il y a quelques lectures suggérées pour vous à la fin de cet article.
Jetons un coup d'œil au plugin existant que nous avons créé dans le dernier article. Votre code devrait ressembler à ceci :
/**
* 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' );
});
Essentiellement, nous avons créé un nouveau plugin. Dans ce plugin, nous avons créé un widget qui affiche une liste de publications personnalisées de la base de connaissances héroïques à partir d'un site Web différent.
Ce que nous allons faire maintenant, c'est modifier cela pour créer également une fonction de recherche.
Étape 1 : Modifier la requête de base pour obtenir des résultats différents
Dans le dernier article, vous vous souviendrez que nous avons expliqué comment OBTENIR une liste de publications, puis comment modifier les paramètres afin que nous puissions obtenir le type de publication personnalisé de la base de connaissances à la place.
Eh bien, ce n'est peut-être pas si surprenant d'apprendre, ce n'est pas tout ce que nous pouvons faire avec la méthode GET. En utilisant les paramètres de filtrage, nous pouvons en fait utiliser n'importe lequel des arguments disponibles lors de l'appel de WP_Query. Par exemple, si nous voulions modifier le nombre de publications affichées, vous pourriez ajouter :
/posts?filter[posts_per_page]=5
Faire l'appel à distance quelque chose comme ceci :
$response = wp_remote_get( 'http://website-with -api.com.com/wp-json/wp/v2/posts?filter[posts_per_page]=5' );
Ou, si nous voulions n'afficher qu'un seul message aléatoire, nous pourrions ajouter :
/posts?filter[orderby]=rand&amp;filter[posts_per_page]=1
Et c'est la même chose pour un paramètre de recherche. Dans une requête WP standard, le paramètre ressemblerait à ceci :
's' => 'keyword'
Par conséquent, notre appel à distance doit ressembler à ceci :
$response = wp_remote_get( 'http://website-with -api.com.com/wp-json/wp/v2/posts?filter[s]=keyword');
C'est assez simple une fois que vous avez compris comment convertir les paramètres de WP_Query dans la chaîne d'URL de l'API.
Pour plus de détails sur les paramètres disponibles, consultez le guide du codex WP_Query.
Cependant, nous ne voulons pas réellement rechercher des publications standard, nous souhaitons rechercher le type de publication personnalisé de la base de connaissances. Cependant, comme nous l'avons vu dans l'article précédent, cela est facile à faire car nous avons rendu notre type de publication personnalisé accessible au public en ajoutant un filtre. Par conséquent, tout ce que nous devons faire ici est d'interroger le type de publication personnalisé de la base de connaissances en échangeant /posts/ avec le nom du type de publication personnalisé. Dans ce cas /ht_kb/ . L'appel à distance ressemblera maintenant à ceci :
$response = wp_remote_get( 'http://website-with-api.com/wp-json/wp/v2/ht_kb?filter[s]=keyword' );
Étape 2 : Le champ de recherche et la personnalisation des résultats
Alors maintenant, nous avons envisagé de modifier la requête pour filtrer par un terme de recherche donné, l'étape suivante consiste à créer un moyen d'obtenir ce terme de recherche.
Tout d'abord, nous devons ajouter un champ de recherche au plugin. Comme il ne s'agira que d'un simple formulaire de recherche, nous pouvons utiliser la fonction get_search_form() déjà configurée par WordPress au lieu de créer un formulaire de recherche séparé.
Dans le fichier du plugin, recherchez la ligne avec le commentaire // Main Widget Content Here dans votre fonction de widget et ajoutez get_search_form(); et modifiez directement en dessous pour qu'il ressemble à ceci:
// 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>';
}
Désormais, lorsque nous afficherons le widget sur la page, vous verrez le formulaire de recherche standard et la liste des publications de la base de connaissances en dessous.

Nous savons en utilisant get_search_form(); que lorsque nous recherchons quelque chose, le paramètre de recherche apparaît dans l'url comme ceci :
/?s=test
's' étant le paramètre $_GET et 'test' étant votre terme de recherche. Par conséquent, il ne reste plus qu'à saisir le terme de recherche à partir de l'URL et à l'utiliser dans la réponse comme suit :
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/' );
}
Ce que fait ce code est de vérifier si $_GET['s'] a été défini et n'est pas vide. Si c'est le cas, vous l'incluez dans votre réponse. Si ce n'est pas le cas, aucune recherche n'est en cours et vous souhaitez afficher tous les messages de la base de connaissances normalement.
Plus de détails sur la fonction get_search_form() peuvent être trouvés ici.
C'est là que nous nous attendrions à ce que cet article se termine, n'est-ce pas ? Après tout, nous avons mis en place un formulaire de recherche qui interroge les publications sur un site Web externe à l'aide de l'API WordPress REST, puis a renvoyé ces résultats en fonction du paramètre de recherche. Pourtant…
Etape 3 : Modifier les résultats affichés
Si nous testons le nouveau widget de recherche, nous pouvons voir que le widget fonctionne comme prévu, cependant, il renverra également les résultats du site Web actuel dans le contenu de la page principale.


C'est à cause du système de modèles WordPress. WordPress utilise la chaîne de requête pour déterminer quel modèle ou ensemble de modèles utiliser. Parce que, lorsque le formulaire de recherche est soumis, il ajoute le paramètre 's' à l'URL, il dit à WordPress d'effectuer une recherche et de rediriger vers la page de résultats de recherche. Qui, dans le thème TwentySixteen est search.php.
Pour plus d'informations, reportez-vous à la documentation sur la hiérarchie des modèles.
C'est très bien si nous voulions effectuer la recherche sur un site Web local et un site Web externe en utilisant l'API en même temps, car les résultats des deux sont affichés. Cependant, dans ce cas, nous ne voulons pas faire cela. Nous voulons uniquement que les résultats renvoyés à l'aide de l'API s'affichent dans le widget. La page principale ne devrait pas être affectée.
Il y a un certain nombre de façons de le faire. Pour cet exemple, nous verrons comment modifier le get_search_form(); fonction pour ne plus utiliser 's' comme paramètre de recherche. Au lieu de cela, il sera remplacé par 'a' pour contourner le problème.
La première étape consiste à modifier réellement le formulaire en créant une nouvelle fonction.
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 fonction elle-même est assez simple, c'est essentiellement un nouveau formulaire à utiliser à la place du formulaire par défaut. Si nous regardons le thème de référence TwentySixteen et inspectons le formulaire de recherche existant, nous remarquons que la seule différence dans le code est le nom de l'entrée de recherche. A l'origine c'était 'name=s' et maintenant c'est 'name=a'. Cela supprime le paramètre 's' de l'URL.
Remarque : Avec cette approche, nous modifions le formulaire de recherche principal pour effectuer une recherche à l'aide de l'API au lieu de rechercher le site Web hôte. Par conséquent, il est important de considérer que si nous utilisons le formulaire de recherche principal n'importe où ailleurs sur le site Web, il ne sera plus redirigé vers les résultats de recherche du site Web hôte. Afin d'avoir deux recherches différentes, la solution la plus simple serait d'ajouter le code de ce nouveau formulaire directement dans le widget au lieu de modifier le get_search_form();
La dernière étape consiste à ajouter le filtre. Cela indique à WordPress de remplacer le formulaire existant par celui-ci à la place. Nous pouvons ensuite coller le bloc de code entier dans le fichier du plugin après la classe du widget. Cela pourrait être inclus dans functions.php du thème à la place, mais en l'incluant dans le plugin, cela signifie que la modification du formulaire n'est effectuée que si le plugin est activé.
Maintenant que nous avons changé le nom de l'entrée en 'a', nous devons également changer le paramètre de recherche réel. Le paramètre apparaîtra désormais dans l'url sous la forme : /?a=test, au lieu de /?s=test et donc en supprimant la partie de la chaîne de requête qui indique à WordPress que cela doit rediriger vers le modèle de résultats de recherche.
Pour pouvoir effectuer une recherche à l'aide du nouveau paramètre, mettez à jour le code écrit précédemment pour l'appel à distance afin d'utiliser le paramètre 'a' au lieu de 's'.
Il devrait maintenant ressembler à ceci :
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/' );
}
Notez que bien que le paramètre de recherche dans $_GET ait changé, cela ne change pas le filtre dans la requête réelle. En effet, la requête WP standard pour la recherche est toujours "s".
Maintenant, lorsque nous testons le widget, nous devrions être en mesure de rechercher les articles de la base de connaissances sur votre site Web externe et de renvoyer les résultats sans être redirigés vers une page de résultats de recherche.

Le code complet du widget ressemble à ceci :
/**
* 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' );
});
Il s'agit d'une implémentation très simple d'un widget de recherche personnalisé utilisant l'API REST. Comme illustré précédemment, nous pourrions ajouter des filtres supplémentaires à la requête pour limiter le nombre de résultats de recherche ou l'ordre dans lequel ils sont affichés. Vous pouvez choisir d'afficher des informations supplémentaires dans le widget, telles que le terme de recherche et le nombre de résultats, ou, si vous connaissez jQuery / Javascript, vous pouvez aller plus loin et ajouter un bel effet AJAX afin que les résultats soient renvoyés sans avoir à rafraîchir la page.
Lectures complémentaires :
- API Widgets (WordPress Codex)
- Introduction à la création de votre premier widget WordPress (Tutsplus)
- Comment créer un widget WordPress personnalisé (WP Beginner)
- Comment créer un plugin de widget pour WordPress (WP Explorer)
