Erstellen eines Such-Widgets mit der WordPress-REST-API

Veröffentlicht: 2016-03-28

WordPress-Entwicklern wird bewusst sein, dass es die REST-API schon seit einiger Zeit gibt, aber Ende letzten Jahres wurde sie in den Kern integriert, was bedeutet, dass sie jetzt in Widgets und Plugins genutzt werden kann.

In diesem Artikel werden wir ein einfaches Such-Widget mit einem Unterschied erstellen. Unter Verwendung der WordPress-REST-API durchsucht dieses Widget eine externe WordPress-Website und zeigt die Ergebnisse im Widget an.

Dieser Beitrag setzt sich mit meinem letzten über Was Sie über die WordPress-REST-API wissen müssen fort

Erstellen Sie eine Wissensdatenbank - der einfache Weg!

Bauen Sie eine durchsuchbare Wissensdatenbank auf und helfen Sie Ihren Kunden, sich selbst zu helfen.

Holen Sie sich das Plugin

Erstellen des Widget-Plugins

Wie im vorherigen Artikel werden einige Grundkenntnisse zum Erstellen von Plugins und Widgets vorausgesetzt. Wenn Sie sich nicht sicher sind, finden Sie am Ende dieses Artikels einige Leseempfehlungen für Sie.

Werfen wir einen Blick auf das vorhandene Plugin, das wir im letzten Artikel erstellt haben. Ihr Code sollte in etwa so aussehen:


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

Im Wesentlichen haben wir ein neues Plugin erstellt. In diesem Plugin haben wir ein Widget erstellt, das eine Liste benutzerdefinierter Beiträge aus der Heroic Knowledge Base von einer anderen Website anzeigt.

Was wir jetzt tun werden, ist, dies zu ändern, um auch eine Suchfunktion zu erstellen.

Schritt 1: Ändern der grundlegenden Abfrage, um andere Ergebnisse zu erhalten

Sie werden sich erinnern, dass wir im letzten Artikel besprochen haben, wie man eine Liste von Beiträgen ERHALTEN und dann die Parameter ändern kann, damit wir stattdessen den benutzerdefinierten Beitragstyp der Wissensdatenbank erhalten.

Nun, es ist vielleicht nicht so überraschend zu erfahren, dass dies nicht alles ist, was wir mit der GET-Methode tun können. Durch die Verwendung der Filterparameter können wir tatsächlich jedes der verfügbaren Argumente verwenden, wenn wir WP_Query aufrufen. Wenn wir beispielsweise die Anzahl der angezeigten Beiträge ändern möchten, könnten Sie Folgendes hinzufügen:


/posts?filter[posts_per_page]=5

Führen Sie den Fernanruf so aus:


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

Oder, wenn wir nur einen zufälligen Beitrag anzeigen wollten, könnten wir hinzufügen:


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

Und das gilt auch für einen Suchparameter. In einer Standard-WP-Abfrage würde der Parameter so aussehen:


's' => 'keyword'

Daher muss unser Remote-Aufruf wie folgt aussehen:


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

Es ist ganz einfach, sobald Sie sich mit der Konvertierung von Parametern aus der WP_Query in die API-URL-Zeichenfolge vertraut gemacht haben.

Ausführliche Informationen zu den verfügbaren Parametern finden Sie im WP_Query-Codex-Leitfaden.

Wir möchten jedoch nicht nach Standardbeiträgen suchen, sondern nach dem benutzerdefinierten Beitragstyp der Wissensdatenbank. Wie wir jedoch im vorherigen Artikel gesehen haben, ist dies einfach, da wir unseren benutzerdefinierten Beitragstyp durch Hinzufügen eines Filters öffentlich verfügbar gemacht haben. Daher müssen wir hier nur den benutzerdefinierten Beitragstyp der Wissensdatenbank abfragen, indem wir /posts/ mit dem Namen des benutzerdefinierten Beitragstyps austauschen. In diesem Fall /ht_kb/ . Der Fernaufruf sieht nun so aus:


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

Schritt 2: Das Suchfeld und die Anpassungsergebnisse

Nachdem wir uns nun mit der Änderung der Abfrage befasst haben, um nach einem bestimmten Suchbegriff zu filtern, besteht der nächste Schritt darin, einen Weg zu finden, um diesen Suchbegriff zu erhalten.

Zuerst müssen wir dem Plugin ein Suchfeld hinzufügen. Da dies nur ein einfaches Suchformular sein wird, können wir die bereits von WordPress eingerichtete Funktion get_search_form() verwenden, anstatt ein separates Suchformular zu erstellen.

Suchen Sie in der Plugin-Datei nach der Zeile mit dem Kommentar // Main Widget Content Here in Ihrer Widget-Funktion und fügen Sie get_search_form(); und bearbeite direkt darunter, sodass es so aussieht:


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

Wenn wir nun das Widget auf der Seite anzeigen, sehen Sie das Standardsuchformular und die Liste der Beiträge aus der Wissensdatenbank darunter.

Standard-Such-Widget

Wir kennen es von der Verwendung von get_search_form(); dass, wenn wir nach etwas suchen, der Suchparameter wie folgt in der URL erscheint:


/?s=test

's' ist der Parameter $_GET und 'test' ist Ihr Suchbegriff. Daher bleibt nur noch, den Suchbegriff aus der URL zu holen und ihn in der Antwort wie folgt zu verwenden:


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

Dieser Code prüft, ob $_GET['s'] gesetzt wurde und nicht leer ist. Wenn dies der Fall ist, fügen Sie dies in Ihre Antwort ein. Wenn nicht, wird keine Suche durchgeführt und Sie möchten alle Beiträge der Wissensdatenbank ganz normal anzeigen.

Weitere Einzelheiten über die Funktion get_search_form() finden Sie hier.

Hier würden wir erwarten, dass dieser Artikel endet, oder? Schließlich haben wir ein Suchformular eingerichtet, das Beiträge auf einer externen Website über die WordPress-REST-API abfragt und diese Ergebnisse dann basierend auf dem Suchparameter zurückgibt. Jedoch…

Schritt 3: Anpassung der angezeigten Ergebnisse

Wenn wir das neue Such-Widget testen, können wir sehen, dass das Widget wie erwartet funktioniert, aber es gibt auch Ergebnisse von der aktuellen Website im Inhalt der Hauptseite zurück.

Suchvorlagen-Ergebnisse
Such-Widget, das Ergebnisse für „Test“ und die Seite anzeigt, die zur Suchergebnisvorlage weiterleitet

Dies liegt am Template-System von WordPress. WordPress verwendet die Abfragezeichenfolge, um zu bestimmen, welche Vorlage oder welcher Vorlagensatz verwendet werden soll. Da beim Absenden des Suchformulars der URL der Parameter „s“ hinzugefügt wird, weist es WordPress an, eine Suche durchzuführen und auf die Suchergebnisseite umzuleiten. Was im TwentySixteen-Thema search.php ist.

Weitere Informationen finden Sie in der Dokumentation zur Vorlagenhierarchie.

Das ist großartig, wenn wir die Suche gleichzeitig auf einer lokalen Website und einer externen Website über die API durchführen wollten, da die Ergebnisse für beide angezeigt werden. Das wollen wir in diesem Fall aber nicht. Wir möchten nur, dass die mithilfe der API zurückgegebenen Ergebnisse im Widget angezeigt werden. Die Hauptseite soll unberührt bleiben.

Dazu gibt es mehrere Möglichkeiten. Für dieses Beispiel sehen wir uns an, wie man get_search_form(); Funktion, 's' nicht mehr als Suchparameter zu verwenden. Stattdessen wird es in 'a' geändert, um das Problem zu umgehen.

Der erste Schritt besteht darin, das Formular tatsächlich zu ändern, indem eine neue Funktion erstellt wird.


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

Die Funktion selbst ist ziemlich einfach, es ist im Grunde ein neues Formular, das anstelle des Standardformulars verwendet werden kann. Wenn wir uns das Referenzthema TwentySixteen ansehen und das vorhandene Suchformular untersuchen, stellen wir fest, dass der einzige Unterschied im Code der Name der Sucheingabe ist. Ursprünglich war es 'name=s' und jetzt ist es 'name=a'. Dadurch wird der Parameter „s“ aus der URL entfernt.

Hinweis: Bei diesem Ansatz ändern wir das Hauptsuchformular so, dass es mithilfe der API sucht, anstatt die Host-Website zu durchsuchen. Daher ist es wichtig zu bedenken, dass, wenn wir das Hauptsuchformular irgendwo anders auf der Website verwenden, es nicht mehr zu den Suchergebnissen der Host-Website umgeleitet wird. Um zwei verschiedene Suchen zu haben, wäre die einfachste Lösung, den Code für dieses neue Formular direkt in das Widget einzufügen, anstatt get_search_form();

Der letzte Schritt besteht darin, den Filter hinzuzufügen. Dies weist WordPress an, das vorhandene Formular stattdessen durch dieses zu ersetzen. Wir können den gesamten Codeblock nach der Widget-Klasse in die Plugin-Datei einfügen. Dies könnte stattdessen in die functions.php des Themes eingebunden werden, aber durch die Aufnahme in das Plugin bedeutet dies, dass die Änderung des Formulars nur vorgenommen wird, wenn das Plugin aktiviert ist.

Nachdem wir den Namen der Eingabe in „a“ geändert haben, müssen wir auch den tatsächlichen Suchparameter ändern. Der Parameter erscheint nun in der URL als: /?a=test anstelle von /?s=test und entfernt daher den Teil der Abfragezeichenfolge, der WordPress mitteilt, dass dies zur Suchergebnisvorlage umleiten soll.

Damit Sie mit dem neuen Parameter suchen können, aktualisieren Sie den zuvor für den Fernaufruf geschriebenen Code so, dass er den Parameter „a“ anstelle von „s“ verwendet.

Es sollte jetzt so aussehen:


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

Beachten Sie, dass sich der Suchparameter in $_GET zwar geändert hat, der Filter in der eigentlichen Abfrage jedoch nicht geändert wird. Dies liegt daran, dass die Standard-WP-Abfrage für die Suche immer noch 's' ist.

Wenn wir jetzt das Widget testen, sollten wir in der Lage sein, die Knowledge Base-Artikel auf Ihrer externen Website zu durchsuchen und die Ergebnisse zurückzugeben, ohne auf eine Suchergebnisseite umgeleitet zu werden.

Such-Widget, das Ergebnisse für „Test“ anzeigt, ohne dass die Seite umgeleitet wird
Such-Widget, das Ergebnisse für „Test“ anzeigt, ohne dass die Seite umgeleitet wird

Der vollständige Code für das Widget sieht folgendermaßen aus:


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

Dies ist eine sehr einfache Implementierung eines benutzerdefinierten Such-Widgets mithilfe der REST-API. Wie bereits dargestellt, könnten wir der Abfrage zusätzliche Filter hinzufügen, um die Anzahl der Suchergebnisse oder die Reihenfolge, in der sie angezeigt werden, einzuschränken. Sie können wählen, ob zusätzliche Informationen im Widget angezeigt werden sollen, z. B. der Suchbegriff und die Anzahl der Ergebnisse, oder Wenn Sie jQuery / Javascript kennen, können Sie dies weiterführen und einen netten AJAX-Effekt hinzufügen, sodass Ergebnisse zurückgegeben werden, ohne dass die Seite aktualisiert werden muss.

Weiterführende Literatur:

  • Widgets-API (WordPress Codex)
  • Einführung in die Erstellung Ihres ersten WordPress-Widgets (Tutsplus)
  • So erstellen Sie ein benutzerdefiniertes WordPress-Widget (WP Beginner)
  • So erstellen Sie ein Widget-Plugin für WordPress (WP Explorer)