WordPress REST API'sini kullanarak bir arama widget'ı oluşturma

Yayınlanan: 2016-03-28

WordPress geliştiricileri, REST API'nin bir süredir var olduğunun farkında olacaklar, ancak geçen yılın sonundan itibaren çekirdeğe entegre edildi, yani artık widget'larda ve eklentilerde kullanılabilir.

Bu yazıda, farkı olan basit bir arama widget'ı oluşturacağız. Bu widget, WordPress REST API'sini kullanarak harici bir WordPress web sitesini arayacak ve sonuçları widget'ta görüntüleyecektir.

Bu gönderi, WordPress REST API hakkında bilmeniz gerekenler hakkındaki son yazımdan devam ediyor.

Bir Bilgi Tabanı Oluşturun - Kolay Yol!

Aranabilir bir bilgi tabanı oluşturun ve müşterilerinizin kendilerine yardım etmesine yardımcı olun.

Eklentiyi Alın

Widget eklentisini oluşturma

Önceki makalede olduğu gibi, eklentiler ve widget'lar oluşturmaya ilişkin bazı temel bilgilerin olduğu varsayılmaktadır. Emin değilseniz, bu makalenin sonunda sizin için önerilen bazı okumalar var.

Son yazıda oluşturduğumuz mevcut eklentiye bir göz atalım. Kodunuz şöyle görünmelidir:


/**
* 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' );
});

Esasen, yeni bir eklenti oluşturduk. Bu eklentide, farklı bir web sitesinden Kahraman Bilgi tabanından özel gönderilerin bir listesini görüntüleyen bir pencere öğesi oluşturduk.

Şimdi yapacağımız şey, bunu bir arama özelliği de oluşturacak şekilde değiştirmek.

Adım 1: Farklı sonuçlar elde etmek için temel sorguyu değiştirme

Son makalede, bir gönderi listesinin nasıl elde edileceğini ve ardından bunun yerine bilgi tabanı özel gönderi türünü alabilmemiz için parametreleri nasıl değiştireceğimizi tartıştığımızı hatırlayacaksınız.

Pekala, öğrenmek o kadar şaşırtıcı olmayabilir, GET yöntemiyle yapabileceğimiz tek şey bu değil. Filtreleme parametrelerini kullanarak, WP_Query'yi çağırırken mevcut olan herhangi bir argümanı gerçekten kullanabiliriz. Örneğin, görüntülenen gönderilerin sayısını değiştirmek istersek şunları ekleyebilirsiniz:


/posts?filter[posts_per_page]=5

Uzaktan aramayı şöyle yapmak:


$response = wp_remote_get( 'http://website-with -api.com.com/wp-json/wp/v2/posts?filter[posts_per_page]=5' );

Veya yalnızca rastgele bir gönderi görüntülemek istiyorsak şunları ekleyebiliriz:


/posts?filter[orderby]=rand&filter[posts_per_page]=1

Ve bu bir arama parametresi için aynıdır. Standart bir WP Sorgusunda parametre şöyle görünür:


's' => 'keyword'

Bu nedenle, uzaktan aramamızın şöyle görünmesi gerekiyor:


$response = wp_remote_get( 'http://website-with -api.com.com/wp-json/wp/v2/posts?filter[s]=keyword');

WP_Query'deki parametreleri API url dizesine dönüştürmeye başladığınızda, bu oldukça basittir.

Hangi parametrelerin mevcut olduğuna ilişkin tüm ayrıntılar için WP_Query kodeksi kılavuzuna bakın.

Aslında standart gönderileri aramak istemiyoruz, bilgi bankası özel gönderi türünü aramak istiyoruz. Ancak, bir önceki makalede gördüğümüz gibi, bunu yapmak kolaydır, çünkü özel gönderi türümüzü bir filtre ekleyerek herkese açık hale getirdik. Bu nedenle, burada tek yapmamız gereken, /posts/ ile özel gönderi türünün adını değiştirerek bilgi bankası özel gönderi türünü sorgulamaktır. Bu durumda /ht_kb/ . Uzaktan arama şimdi şöyle görünecek:


$response = wp_remote_get( 'http://website-with-api.com/wp-json/wp/v2/ht_kb?filter[s]=keyword' );

2. Adım: Arama kutusu ve sonuçları uyarlama

Şimdi sorguyu belirli bir arama terimine göre filtrelemek için değiştirmeye baktık, sonraki adım bu arama terimini almanın bir yolunu oluşturmaktır.

Öncelikle eklentiye bir arama kutusu eklememiz gerekiyor. Bu sadece basit bir arama formu olacağından, ayrı bir arama formu oluşturmak yerine WordPress tarafından zaten kurulmuş olan get_search_form() işlevini kullanabiliriz.

Eklenti dosyasında, widget işlevinizin içinde // Main Widget Content Here yorumunu içeren satırı arayın ve get_search_form(); ve aşağıdaki gibi görünecek şekilde doğrudan altında düzenleyin:


// 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>';
}

Şimdi widget'ı sayfada görüntülediğimizde, standart arama formunu ve bunun altında Bilgi Bankası'ndaki gönderilerin listesini göreceksiniz.

standart arama widget'ı

get_search_form(); kullanarak biliyoruz. bir şey aradığımızda, arama parametresi url'de şöyle görünür:


/?s=test

's' $_GET parametresi ve 'test' arama teriminizdir. Bu nedenle, geriye kalan tek şey, arama terimini URL'den alıp yanıtta şu şekilde kullanmaktır:


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/' );
}

Bu kodun yaptığı, $_GET['s'] öğesinin ayarlanıp ayarlanmadığını ve boş olmadığını kontrol etmektir. Varsa/varsa, cevabınıza dahil edersiniz. Değilse, arama yapılmamaktadır ve tüm bilgi bankası gönderilerini normal şekilde göstermek istiyorsunuz.

get_search_form() işlevi hakkında daha fazla ayrıntı burada bulunabilir.

Bu makalenin bitmesini beklediğimiz yer burası değil mi? Sonuçta, WordPress REST API'sini kullanarak harici bir web sitesindeki gönderileri sorgulayan ve ardından bu sonuçları arama parametresine göre döndüren bir arama formu oluşturduk. Ancak…

Adım 3: Görüntülenen sonuçları değiştirme

Yeni arama widget'ını test edersek, widget'ın beklendiği gibi çalıştığını görebiliriz, ancak ana sayfa içeriğinde mevcut web sitesinden sonuçları da döndürecektir.

arama şablonu sonuçları
'Test' sonuçlarını ve arama sonuçları şablonuna yönlendirilen sayfayı gösteren arama widget'ı

Bunun nedeni WordPress şablonlama sistemidir. WordPress, hangi şablonun veya şablon kümesinin kullanılacağını belirlemek için sorgu dizesini kullanır. Arama formu gönderildiğinde URL'ye 's' parametresini eklediğinden, WordPress'e bir arama yapmasını ve arama sonuçları sayfasına yönlendirmesini söylüyor. TwentySixteen temasında search.php var.

Daha fazla bilgi için şablon hiyerarşi belgelerine bakın.

Aramayı yerel bir web sitesinde ve harici bir web sitesinde aynı anda API kullanarak yapmak istiyorsak bu harika bir şey çünkü her ikisinin sonuçları da görüntüleniyor. Ancak, bu durumda bunu yapmak istemiyoruz. Yalnızca API kullanılarak döndürülen sonuçların widget'ta görüntülenmesini istiyoruz. Ana sayfa etkilenmeden kalmalıdır.

Bunu yapmanın çeşitli yolları var. Bu örnek için, get_search_form(); öğesinin nasıl değiştirileceğine bakacağız. arama parametresi olarak artık 's' kullanmama işlevi. Bunun yerine sorunu atlamak için 'a' olarak değiştirilecektir.

İlk adım, yeni bir işlev oluşturarak formu gerçekten değiştirmektir.


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 );

Fonksiyonun kendisi oldukça basittir, temelde varsayılan form yerine kullanılacak yeni bir formdur. Referans TwentySixteen temasına bakar ve mevcut arama formunu incelersek, koddaki tek farkın arama girişinin adı olduğunu not ederiz. Başlangıçta 'isim=s' idi ve şimdi 'isim=a' oldu. Bu, 's' parametresini URL'den kaldırır.

Not: Bu yaklaşımla, ana arama formunu, ana web sitesinde arama yapmak yerine API kullanarak arama yapacak şekilde değiştiririz. Bu nedenle, ana arama formunu web sitesinde başka herhangi bir yerde kullanırsak, artık ana web sitesinin web sitesindeki arama sonuçlarına yönlendirilmeyeceğini dikkate almak önemlidir. İki farklı arama yapabilmek için en kolay çözüm, get_search_form();

Son adım filtreyi eklemektir. Bu, WordPress'e mevcut formu bunun yerine bununla değiştirmesini söyler. Widget sınıfından sonra tüm kod bloğunu eklenti dosyasına yapıştırabiliriz. Bu, bunun yerine temanın function.php dosyasına dahil edilebilir, ancak bunu eklentiye dahil etmek, formdaki değişikliğin yalnızca eklenti etkinleştirildiğinde yapıldığı anlamına gelir.

Şimdi girdinin adını 'a' olarak değiştirdiğimize göre, gerçek arama parametresinin de ne olacağını değiştirmeliyiz. Parametre artık url'de /?s=test yerine /?a=test olarak görünecek ve bu nedenle, sorgu dizesinin WordPress'e bunun arama sonuçları şablonuna yönlendirmesi gerektiğini söyleyen kısmı kaldırılacaktır.

Yeni parametreyi kullanarak arama yapabilmeniz için daha önce uzaktan arama için yazılan kodu 's' yerine 'a' parametresini kullanacak şekilde güncelleyin.

Şimdi şöyle görünmelidir:


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/' );
}

$_GET içindeki arama parametresinin değişmesine rağmen bunun gerçek sorgudaki filtreyi değiştirmediğine dikkat edin. Bunun nedeni, arama için standart WP Sorgusunun hala 's' olmasıdır.

Şimdi, widget'ı test ettiğimizde, harici web sitenizdeki Bilgi Bankası makalelerini arayabilmeli ve sonuçları bir arama sonuçları sayfasına yönlendirilmeden döndürebilmeliyiz.

Sayfa yönlendirmesi olmadan 'test' sonuçlarını görüntüleyen arama widget'ı
Sayfa yönlendirmesi olmadan 'test' sonuçlarını görüntüleyen arama widget'ı

Widget'ın tam kodu şöyle görünür:


/**
 * 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' );
});

Bu, REST API kullanan özel bir arama widget'ının çok basit bir uygulamasıdır. Daha önce gösterildiği gibi, arama sonuçlarının sayısını veya görüntülendikleri sırayı sınırlamak için sorguya ek filtreler ekleyebiliriz. Widget'ta arama terimi ve sonuç sayısı gibi ek bilgileri görüntülemeyi seçebilir veya, jQuery/Javascript biliyorsanız, bunu daha da ileri götürebilir ve sonuçların sayfayı yenilemeye gerek kalmadan döndürülmesi için güzel bir AJAX efekti ekleyebilirsiniz.

Daha fazla okuma:

  • Widget'lar API'si (WordPress Codex)
  • İlk WordPress widget'ınızı (Tutsplus) oluşturmaya giriş
  • Özel bir WordPress widget'ı nasıl oluşturulur (WP Başlangıç)
  • WordPress için bir widget eklentisi nasıl oluşturulur (WP Explorer)