WordPress: Schnelleinstieg in die Entwicklung eigener WordPress-Widgets
Bis zur WordPress-Version 2.2.x konnte man die Anzeige zusätzlicher Blöcke mit Inhalten nur durch die Anpassung eines Themes erreichen. Seit WordPress 2.3 ist das anders: Mit so genannten Widgets [1] lässt sich ein Theme um zusätzliche Funktionen oder Inhalte erweitern, ohne dass man dabei in das Theme eingreifen muss.
Per Drag & Drop kann man der Sidebar eines Themes im Backend von WordPress bequem ein neues Widget hinzufügen. Je nach Theme stehen einem dabei entweder nur eine oder auch mehrere Seitenleisten zur Verfügung, die Widgets aufnehmen können. Für Anwender haben Widgets den Vorteil, dass sie sie ohne Kenntnisse von HTML oder PHP nutzen können. Darüber hinaus bleiben die eingebundenen Widgets bei einem Wechsel des Themes erhalten.
Seit Version 2.8 stellt WordPress Entwicklern eine eigenständige API [2] zur Verfügung, welche die Entwicklung und Bereitstellung von Widgets stark vereinfacht. Die folgenden Ausführungen beziehen sich auf die Programmierung von Widgets ab WordPress 2.8.
Voraussetzung für Widgets in Themes
Um Widgets innerhalb eines Themes einsetzen zu können, muss das Theme Widgets unterstützen. Ein Theme ist generell dann in der Lage, mit Widgets umzugehen, wenn zwei Bedingungen erfüllt sind. Im Theme selbst muss ein entsprechender Bereich in der Seitenleiste (sidebar) vorhanden sein, der dynamisch Widgets aufnehmen kann. Folgende Ergänzung ist dabei notwendig:
<?php if ( !function_exists('dynamic_sidebar') || !dynamic_sidebar($name_or_number) ) : endif; ?>
Listing 1
Die Widgets erscheinen später dort, wo der Code-Schnipsel eingefügt wird. Wenn mehr als ein Bereich für Widgets genutzt werden soll, ist die Verwendung des optionalen Parameters unerlässlich. Es kann entweder eine ID oder ein Name (Typ: String) übergeben werden. In „sidepar.php“ können vor und nach dem Widget-Befehl noch HTML- oder WordPress-Tags verwendet werden. Neben der Möglichkeit, die Sidebar mit mehreren dynamischen Bereichen auszustatten, kann man auch jeden anderen Bereich innerhalb eines Themes auf die gleiche Weise widgetfähig machen.
Die zweite Voraussetzung für die Nutzung von Widgets innerhalb eines Themes ist ein Zusatz in der Datei „functions.php“. Sollte diese Datei noch nicht im Ordner des Themes vorhanden sein, so muss sie neu angelegt werden. Innerhalb der Datei wird folgender PHP-Code eingetragen:
<?php if ( function_exists('register_sidebar') ) register_sidebar(array( 'name'=> $name_or_number, 'before_widget' => '', 'after_widget' => '', 'before_title' => '' ,'after_title' => ‚‘,)); ?>
Listing 2
Der Parameter „$name_or_number“ bezieht sich dabei auf den Bezeichner, der zuvor beim Aufruf der Funktion „dynamic_sidebar“ an anderer Stelle im Theme gewählt wurde. Mit Hilfe von „before_widget“, „after_widget“, „before_title“ und „after_title“ kann zusätzlich noch festgelegt werden, was vor und nach dem Widget beziehungsweise dem Titel stehen soll. Das ist hilfreich, wenn zum Beispiel ein Widget von einem div-Element mit einer bestimmten Klasse umschlossen werden soll.
Sind mehrere dynamische Bereiche vorhanden, so muss für jeden ein eigener Code-Block erstellt werden, sofern die Abfrage nicht von einer Schleife umschlossen wurde [3] oder die alternative Funktion „register_sidebars“ [4] verwendet wird.
Struktur eines Widget
Um ein Widget zu erstellen, muss zunächst die Standard-Widget-Klasse eingebunden werden. Die Basisklasse enthält alle notwendigen Grundfunktionen und lässt sich erweitern, um ein funktionsfähiges Widget zu erhalten.
<?php class Beispiel_Widget extends WP_Widget { function Beispiel_Widget() { // Konstruktor } function widget($args, $instance) { // Ausgabefunktion } function update($new_instance, $old_instance) { // Speichern der Optionen } function form($instance) { // Formular des Widgets im Backend } } register_widget('Beispiel_Widget'); ?>
Listing 3
Innerhalb des Konstruktors muss die Methode „WP_Widget“ der Basisklasse zum Erzeugen des Widget aufgerufen werden:
parent::WP_Widget(false, $name = 'Name des Widgets');
Listing 4
Der erste Parameter wird üblicherweise auf den Wert false gesetzt, sodass WordPress automatisch eine eindeutige ID für das Widget vergibt. Der Name des Widget wird entsprechend im Backend von WordPress auf der Konfigurationsseite angezeigt. Beim Aufruf des Konstruktors lassen sich noch optional zwei weitere Parameter in Form eines Array übergeben: „$widget_options“ und „$control_options“. Häufig ist es nützlich, wenn Widgets zusätzlich zum Namen auch eine kurze Beschreibung enthalten, die im Backend angezeigt wird. Durch einen Aufruf mit dem entsprechenden Parameter lässt sich dies schnell umsetzen.
Es handelt sich dabei nicht um die Beschreibung auf der Plugin-Seite, sondern um jene auf der Seite für die Widgets.
$wp_options = array('description'=>'Eine kleine Beschreibung'); parent::WP_Widget(false, $name = 'Beispiel Widget',$wp_options);
Listing 5
Die drei Methoden „widget“, „update“ und „form“ sollte man auch in einer eigenen Widget-Klasse verwenden. Mit „widget“ erfolgt die Ausgabe im Frontend. Über „update“ werden Parameter des Widget gespeichert, die sich im Backend über das durch die Methode „form“ dargestellte Formular einstellen lassen.
Nach der eigentlichen Klasse erfolgt in PHP noch der Aufruf der Funktion „register_widget“, um das Widget innerhalb von WordPress zu registrieren.
Anzeige der Daten im Frontend
Anhand eines einfachen Zitat-Widget wird nachfolgend die Nutzung der einzelnen Methoden verdeutlicht. Ausgegeben werden die Daten im Frontend über die Methode widget($args, $instance). Neben den eigentlichen Daten empfiehlt es sich, auch den Titel des Widget auszugeben. Dabei wird die Ausgabe des Titels modifiziert durch das, was um den Titel herumgewickelt werden soll.
Umschlossen wird die gesamte Ausgabe dann von dem, was vor und nach dem Widget im Rahmen des Themes festgelegt ist. Verantwortlich dafür sind die Werte, die beim Aufruf von „register_sidebar“ im Theme angegeben wurden. Eine einfache Ausgabe sieht dann entsprechend so aus:
<function widget($args, $instance) { extract( $args ); $title = apply_filters('widget_title', $instance['title']); echo $before_widget; if ( $title ) echo $before_title . $title . $after_title; echo '<quote>'.$instance['zitat'].'</quote>'; echo '<i>'.$instance['quelle'].'</i>'; echo $after_widget; }
Listing 6
Die Methode wird mit den beiden bereits genannten Parametern „$args“ und „$instance“ aufgerufen. Zunächst werden mit Hilfe der Funktion „extract“ Argumente wie „$before_title“ oder „$after_widget“ zur Verfügung gestellt. Anschließend wird ein so genannter Filter-Haken (Hook) [5] für den Titel des Widget eingebunden. Innerhalb der Methode stehen die Argumente von „register_sidebar“ als einzelne Variablen zur Verfügung. Ihr Wert richtet sich immer danach, was im Theme dafür angegeben wurde und lässt sich nicht im Backend ändern. Die Instanz-Variablen dagegen werden unmittelbar durch die im Backend festgelegten Optionen des Widget beeinflusst. Dazu bedarf es allerdings eines entsprechenden Formulars, über das die Werte eingegeben werden können.
Backend-Formular für Widgets erstellen
Um ein Optionsformular für Widgets zu generieren, genügen bereits wenige Zeilen Code. Die Widget-Basisklasse von WordPress stellt Methoden wie „get_field_id()“ und „get_field_name()“ zur Verfügung, die den größten Teil der Arbeit übernehmen.
function form($instance) { $default_settings = array( 'title' => 'Zitat des Tages', 'zitat' => '', 'quelle' => '' ); $instance = wp_parse_args( (array) $instance, $default_settings ); ?> <p> <label for="<?php echo $this->get_field_id( 'title' ); ?>">Titel:</label> <input id="<?php echo $this->get_field_id( 'title' ); ?>" name="<?php echo $this->get_field_name( 'title' ); ?>" value="<?php echo $instance['title']; ?>" style="width:100%;" /> </p> <p> <label for="<?php echo $this->get_field_id( 'zitat' ); ?>">Zitat:</label> <input id="<?php echo $this->get_field_id( 'zitat' ); ?>" name="<?php echo $this->get_field_name( 'zitat' ); ?>" value="<?php echo $instance['zitat']; ?>" style="width:100%;" /> </p> <p> <label for="<?php echo $this->get_field_id( 'quelle' ); ?>">Quelle:</label> <input id="<?php echo $this->get_field_id( 'quelle' ); ?>" name="<?php echo $this->get_field_name( 'quelle' ); ?>" value="<?php echo $instance['quelle']; ?>" style="width:100%;" /> </p> <?php }
Listing 7
Zunächst werden Standardwerte für das Widget hinterlegt, die benutzt werden, wenn das Widget im Backend in die Seitenleiste gezogen wird. Diese Werte können später überschrieben werden. Dem Array „$instance“ werden dann entweder die Standardwerte zugewiesen oder, sofern vorhanden, die Werte der Instanz aus den Optionsfeldern.
Der nachfolgende HTML-Teil stellt die Eingabemaske zur Verfügung. Über die beiden Methoden „get_field_id“ und „get_field_name“ werden dem Formular automatisch die richtigen Bezeichner zugeordnet, sodass die Werte beim späteren Speichern korrekt übertragen werden. Über das Array „$instance“ lassen sich darüber hinaus in den Eingabefeldern die bisher gespeicherten Werte anzeigen.
Speichern der Einstellungen
Damit die im Formular eingetragenen Werte auch gespeichert werden können, fehlt noch die Methode zur Speicherung der im Backend eingetragenen Werte. Sie wird immer dann aufgerufen, wenn der Button „Speichern“ des Widget angeklickt wird.
function update($new_instance, $old_instance) { $instance = $old_instance; $instance['title'] = strip_tags( $new_instance['title'] ); $instance['zitat'] = strip_tags( $new_instance['zitat'] ); $instance['quelle'] = $new_instance['quelle']; return $instance; }
Listing 8
In den Methoden zum Speichern der Daten bietet es sich an, die Eingabe aus dem Formular entsprechend zu filtern und gegebenenfalls noch weiter zu modifizieren. In der unsicheren Kurzform würde die Methode nur mit einer Zeile Code auskommen, bei der mittels „return $new_instance;“ die neuen Werte zurückgegeben werden.
Abschließend muss das Widget innerhalb von WordPress eingebunden werden. In diesem Fall geschieht dies über den Hook „widgets_init“, um das Widget zu registrieren. Wichtig dabei ist, dass dieser Aufruf außerhalb der Klasse erfolgen muss.
Fazit
Das Programmieren eigener Widgets für WordPress gestaltet sich recht problemlos, wie das obige Beispiel zum grundlegenden Aufbau von Widgets verdeutlicht. Das Beispiel-Widget kann man zudem noch lokalisieren. In diesem konkreten Fall, aber auch im Allgemeinen, sollte man weitere Sicherheitsabfragen einrichten, um die Eingabe im Backend mit den entsprechenden Funktionen zu filtern, die WordPress zur Verfügung stellt. Gerade bei komplexeren Widgets bietet es sich zudem an, PHP-Code und HTML-Elemente sauber voneinander zu trennen und die HTML-Bestandteile in ein Template auszulagern.