Criando um widget de pesquisa usando a API REST do WordPress
Publicados: 2016-03-28Os desenvolvedores do WordPress estarão cientes de que a API REST já existe há algum tempo, mas no final do ano passado ela foi integrada ao núcleo, o que significa que agora pode ser aproveitada em widgets e plugins.
Neste artigo, vamos construir um widget de pesquisa simples com uma diferença. Usando a API REST do WordPress, este widget pesquisará um site externo do WordPress e exibirá os resultados no widget.
Este post continua do meu último sobre O que você precisa saber sobre a API REST do WordPress
Crie uma base de conhecimento pesquisável e ajude seus clientes a se ajudarem.
Obtenha o plug-inConstruindo o plug-in do widget
Como no artigo anterior, alguns conhecimentos básicos de construção de plugins e widgets são assumidos. Se você não tiver certeza, há algumas sugestões de leitura para você no final deste artigo.
Vamos dar uma olhada no plugin existente que criamos no último artigo. Seu código deve ficar mais ou menos assim:
/**
* 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' );
});
Essencialmente, criamos um novo plugin. Nesse plugin, criamos um widget que exibe uma lista de postagens personalizadas da base Heroic Knowledge de um site diferente.
O que vamos fazer agora é alterar isso para criar um recurso de pesquisa também.
Etapa 1: alterar a consulta básica para obter resultados diferentes
No último artigo, você se lembrará de que discutimos como obter uma lista de postagens e, em seguida, como alterar os parâmetros para que pudéssemos obter o tipo de postagem personalizado da base de conhecimento.
Bem, pode não ser tão surpreendente aprender, isso não é tudo o que podemos fazer com o método GET. Usando os parâmetros de filtragem, podemos usar qualquer um dos argumentos disponíveis ao chamar WP_Query. Por exemplo, se quisermos alterar o número de postagens exibidas, você pode adicionar:
/posts?filter[posts_per_page]=5
Fazendo a chamada remota algo assim:
$response = wp_remote_get( 'http://website-with -api.com.com/wp-json/wp/v2/posts?filter[posts_per_page]=5' );
Ou, se quiséssemos exibir apenas uma postagem aleatória, poderíamos adicionar:
/posts?filter[orderby]=rand&amp;filter[posts_per_page]=1
E isso é o mesmo para um parâmetro de pesquisa. Em uma consulta WP padrão, o parâmetro ficaria assim:
's' => 'keyword'
Portanto, nossa chamada remota precisa ficar assim:
$response = wp_remote_get( 'http://website-with -api.com.com/wp-json/wp/v2/posts?filter[s]=keyword');
É bem simples quando você começa a converter parâmetros do WP_Query na string de URL da API.
Para obter detalhes completos sobre quais parâmetros estão disponíveis, consulte o guia do códice WP_Query.
Na verdade, não queremos pesquisar postagens padrão, queremos pesquisar o tipo de postagem personalizada da base de conhecimento. No entanto, como vimos no artigo anterior, isso é fácil de fazer porque disponibilizamos publicamente nosso tipo de postagem personalizado adicionando um filtro. Portanto, tudo o que precisamos fazer aqui é consultar o tipo de postagem personalizado da base de conhecimento trocando /posts/ pelo nome do tipo de postagem personalizado. Neste caso /ht_kb/ . A chamada remota agora ficará assim:
$response = wp_remote_get( 'http://website-with-api.com/wp-json/wp/v2/ht_kb?filter[s]=keyword' );
Etapa 2: a caixa de pesquisa e a personalização dos resultados
Então, agora que analisamos a alteração da consulta para filtrar por um determinado termo de pesquisa, a próxima etapa é criar uma maneira de obter esse termo de pesquisa.
Em primeiro lugar, precisamos adicionar uma caixa de pesquisa ao plugin. Como este será apenas um formulário de pesquisa simples, podemos usar a função get_search_form() já configurada pelo WordPress em vez de criar um formulário de pesquisa separado.
No arquivo do plugin, procure a linha com o comentário // Main Widget Content Aqui dentro da sua função widget e adicione get_search_form(); e edite diretamente abaixo dele para que fique assim:
// 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>';
}
Agora, quando visualizarmos o widget na página, você verá o formulário de pesquisa padrão e a lista de postagens da Base de conhecimento abaixo dele.

Sabemos usando get_search_form(); que quando procuramos por algo, o parâmetro search aparece na url assim:
/?s=test
's' sendo o parâmetro $_GET e 'test' sendo seu termo de pesquisa. Portanto, tudo o que resta é pegar o termo de pesquisa do URL e usá-lo na resposta da seguinte forma:
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/' );
}
O que esse código faz é verificar se $_GET['s'] foi definido e não está vazio. Se tiver/é, inclua-o na sua resposta. Caso contrário, uma pesquisa não está sendo realizada e você deseja mostrar todas as postagens da base de conhecimento normalmente.
Mais detalhes sobre a função get_search_form() podem ser encontrados aqui.
Este é o lugar onde esperaríamos que este artigo terminasse, certo? Afinal, configuramos um formulário de pesquisa que consulta postagens em um site externo usando a API REST do WordPress e retornamos esses resultados com base no parâmetro de pesquisa. Contudo…
Etapa 3: alterando os resultados exibidos
Se testarmos o novo widget de pesquisa, podemos ver que o widget funciona conforme o esperado, no entanto, ele também retornará resultados do site atual no conteúdo da página principal.

Isso é por causa do sistema de templates do WordPress. O WordPress usa a string de consulta para determinar qual modelo ou conjunto de modelos usar. Porque, quando o formulário de pesquisa é enviado, ele adiciona o parâmetro 's' à URL, está dizendo ao WordPress para realizar uma pesquisa e redirecionar para a página de resultados da pesquisa. Que, no tema TwentySixteen é search.php.

Para obter mais informações, consulte a documentação da hierarquia de modelos.
Isso é ótimo se quisermos realizar a pesquisa em um site local e em um site externo usando a API ao mesmo tempo, pois os resultados de ambos são exibidos. No entanto, neste caso, não queremos fazer isso. Queremos apenas que os resultados retornados usando a API sejam exibidos no widget. A página principal deve permanecer inalterada.
Existem várias maneiras de fazer isso. Para este exemplo, veremos como alterar o get_search_form(); função para não usar mais 's' como seu parâmetro de pesquisa. Em vez disso, ele será alterado para 'a' para contornar o problema.
O primeiro passo é realmente modificar o formulário criando uma nova função.
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 );
A função em si é bem simples, é basicamente um novo formulário para usar em vez do formulário padrão. Se olharmos para o tema TwentySixteen de referência e inspecionarmos o formulário de pesquisa existente, notamos que a única diferença no código é o nome da entrada de pesquisa. Originalmente era 'name=s' e agora é 'name=a'. Isso remove o parâmetro 's' da URL.
Observação: com essa abordagem, modificamos o formulário de pesquisa principal para pesquisar usando a API em vez de pesquisar no site host. Portanto, é importante considerar que, se usarmos o formulário de pesquisa principal em qualquer outro lugar do site, ele não redirecionará mais para os resultados de pesquisa do site do site host. Para ter duas pesquisas diferentes, a solução mais fácil seria adicionar o código para este novo formulário diretamente no widget em vez de alterar o get_search_form();
O último passo é adicionar o filtro. Isso diz ao WordPress para substituir o formulário existente por este. Podemos colar todo o bloco de código no arquivo de plug-in após a classe do widget. Isso poderia ser incluído no functions.php do tema, mas ao incluí-lo no plugin, significa que a alteração no formulário só é feita se o plugin estiver ativado.
Agora que alteramos o nome da entrada para 'a', precisamos alterar também qual será o parâmetro de pesquisa real. O parâmetro agora aparecerá na url como: /?a=test, em vez de /?s=test e, portanto, removendo a parte da string de consulta que informa ao WordPress que isso deve redirecionar para o modelo de resultados de pesquisa.
Para que você possa pesquisar usando o novo parâmetro, atualize o código escrito anteriormente para chamada remota para usar o parâmetro 'a' em vez de 's'.
Agora deve ficar assim:
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/' );
}
Observe que, embora o parâmetro de pesquisa em $_GET tenha sido alterado, isso não altera o filtro na consulta real. Isso ocorre porque o WP Query padrão para pesquisa ainda é 's'.
Agora, quando testarmos o widget, poderemos pesquisar os artigos da Base de Conhecimento em seu site externo e retornar os resultados sem ser redirecionado para uma página de resultados de pesquisa.

O código completo para o widget é assim:
/**
* 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' );
});
Esta é uma implementação muito simples de um widget de pesquisa personalizado usando a API REST. Conforme ilustrado anteriormente, poderíamos adicionar filtros adicionais à consulta para limitar o número de resultados de pesquisa ou a ordem em que são exibidos. Você pode optar por exibir informações adicionais no widget, como o termo de pesquisa e o número de resultados, ou, se você conhece jQuery / Javascript, você pode ir mais longe e adicionar um bom efeito AJAX para que os resultados sejam retornados sem a necessidade de atualizar a página.
Leitura adicional:
- API de widgets (WordPress Codex)
- Introdução à criação do seu primeiro widget WordPress (Tutsplus)
- Como criar um widget WordPress personalizado (WP Beginner)
- Como criar um plugin de widget para WordPress (WP Explorer)
