WordPress: Mit PHP eigenes Widget (Plugin) erstellen

Auch wenn man WordPress seit vielen Jahren nutzt, kommt man nur selten in die Verlegenheit, ein Plugin selbst zu programmieren. Auch wenn es einem oftmals in den Fingern juckt und man kurz davor ist, ein eigenes Widget zu erstellen, zeigt einem eine kurze Suche, dass es bereits eine fertige und kostenlose Lösung gibt. Warum dann also selbst programmieren?
Nach vielen Jahren der WordPress-Nutzung kam ich vor wenigen Tagen zum ersten Mal an eine Stelle, an der ich ein eigenes Widget programmiert habe. Vielleicht hätte nach einer längeren Suche sich eine fertige Lösung ergeben, doch da es – wie immer – mal wieder schnell, schnell gehen musste, griff ich in die Tasten. Im vorliegenden Fall musste ein fertiges Theme genutzt werden, in dessen Footer-Bereich mehrspaltig eine Datenbankabfrage angezeigt werden sollte. Jede Spalte wurde vom Theme mit einem eigenen Widget bedient. Im Kundenfall jedoch sollten in allen drei Spalten nicht unterschiedliche Abfragen, sondern eine Abfrage verteilt auf drei Spalten angezeigt werden.
Wordpress-Plugin-selbst-programmiertDie einfachste wie auch schnellste Lösung wäre sicherlich der Eingriff in das (fremde) Theme gewesen, was aber die Wartbarkeit bzw. das Update des Themes erschwert hätte. So lautete der Auftrag, dies per Widget zu lösen.
Untenstehend zeige ich Euch eine Basisklasse „MyTestWidget“, die als Layout für die meisten Plugins dienen kann. Geht folgendermaßen beim Erstellen vor:

  1. Kopiert den Code in ein Textpad, speichert den Code als [mein-widget-Name].php
  2. Passt im Code die Stellen „MyTest Widget“ und „My_Test_Widget“ entsprechend an
  3. Kopiert den Code in den WordPress-Ordner „/wp-content/plugins“. Im WordPress Backend sollte nun unter „Plugins“ Euer Plugin auftauchen. Wenn Ihr es aktiviert, erscheint auf der Layout/Widgets Seite das Widget, welches Ihr in den entsprechenden Widget-Area ziehen könnt.
  4. widget-einstellungNach diesem kurzen Test müsst Ihr natürlich das Plugin entsprechend anpassen. In der Funktion „public function form($instance)“ werden die Parameter abgehandelt, die im Widget-Bereich vom Admin gesetzt werden sollen. Im Code findet Ihr die Variablen ‚footer-books-title‘ , ‚footer-books-start‘  und ‚footer-books-ende‘ . Passt hier Eure Angaben an. Ein Beispielcode, wie mit einer HTML-Texteingabe umzugehen ist, findet Ihr auskommentiert im Code.
  5. Die Eingaben werden im Plugin auf Richtigkeit geprüft und in der WordPress-Datenbank gespeichert. Diese Stellen sind ebenfalls anzupassen.
  6. Nun wird es endlich spannend. In der Funktion „public function widget($args, $instance)“ erfolgt endlich die Ausgabe des Widgets. Im Code könnt Ihr sehen, wie man auf die Widget-Parameter und die Datenbank zugreift. Der Beispielcode hier macht relativ wenig; er dient nur als Demonstration.
  7. Und das war´s auch schon. Die restlichen Funktionen dienen der Registrierung etc. Weitere Infos findet Ihr wie immer unter wordpress.org
<?php
/**
 * Plugin Name: MyTest Widget
 * Plugin URI: http://sirmark.de
 * Description: Basis-Code für ein WordPress - Widget
 * Version: 1.0
 * Author: sirmark
 * Author URI: http://sirmark.de
 */
if(!class_exists('My_Test_Widget')) {
    /**
     * Class My_Test_Widget
     * Aufbau eines Test Widgets
     */
    class My_Test_Widget extends WP_Widget {
        private $var_sTextdomain; // Variable Textdomain: Übersetzungen des Widgets

        /**
         * Konstruktorfunktion (PHP4).
         *
         * Diese Funktion muss den gleichen Namen haben, wie das Klasse des Widgets.
         * Somit wird diese Funktion direkt nach dem Initialisieren der Klasse
         * aufgerufen und ausgeführt. Da dies der Konstruktor für PHP4 ist wird durch diesen
         * direkt die Konstruktor-Funktion für PHP5 aufgerufen.
         *
         * @see My_Test_Widget::__construct()
         */
        public function My_Test_Widget() {
            My_Test_Widget::__construct();
        } // END function My_Test_Widget()

        /**
         * Konstruktorfunktion (PHP5).
         *
         * @param array $widget_options Optional Passed to wp_register_sidebar_widget()
         *   - description: shown on the configuration page
         *   - classname
         * @param array $control_options Optional Passed to wp_register_widget_control()
         *   - width: required if more than 250px
         *   - height: currently not used but may be needed in the future
         */
        public function __construct() {
            $this->var_sTextdomain = 'my-Test-widget';

            /**
             * Übersetzungsfunktion für das Widget aktivieren.
             * Die Sprachdateien liegen im Ordner "l10n" innerhalb des Widgets.
             */
            if(function_exists('load_plugin_textdomain')) {
                load_plugin_textdomain($this->var_sTextdomain, PLUGINDIR . '/' . dirname(plugin_basename(__FILE__)) . '/l10n', dirname(plugin_basename(__FILE__)) . '/l10n');
            }

            $widget_options = array(
                'classname' => 'My_Test_Widget',
                'description' => __('Kurze Beschreibung des Widgets.', $this->var_sTextdomain)
            );

            $control_options = array();

            $this->WP_Widget('My_Test_Widget', __('My TestWidget', $this->var_sTextdomain), $widget_options, $control_options);
        } // END function __construct()

        /**
         * Widgetformular – dient zur Einstellung des Widgets
         *
         * @see WP_Widget::form()
         */
        public function form($instance) {
            /**
             * Standardwerte
             *
             * @var array
             */
            $instance = wp_parse_args((array) $instance, array(
                'footer-books-title' => '',
                'footer-books-start' => '0',
                'footer-books-ende' => '5'
            ));

            // Titel
            echo '<p style="border-bottom: 1px solid #DFDFDF;"><strong>' . __('Title', $this->var_sTextdomain) . '</strong></p>';
            echo '<p><input id="' . $this->get_field_id('footer-books-title') . '" name="' . $this->get_field_name('footer-books-title') . '" type="text" value="' . $instance['footer-books-title'] . '" /></p>';
            echo '<p style="clear:both;"></p>';

            ?>
            <p>
                <label for="<?php echo $this->get_field_id('footer-books-start'); ?>"><?php echo 'Start:'; ?></label>
                <input id="<?php echo $this->get_field_id('footer-books-start'); ?>" name="<?php echo $this->get_field_name('footer-books-start'); ?>" type="text" value="<?php echo $instance['footer-books-start']; ?>" />
            </p>
            <p>
                <label for="<?php echo $this->get_field_id('footer-books-ende'); ?>"><?php echo 'Anzahl:'; ?></label>
                <input id="<?php echo $this->get_field_id('footer-books-ende'); ?>" name="<?php echo $this->get_field_name('footer-books-ende'); ?>" type="text" value="<?php echo $instance['footer-books-ende']; ?>" />
            </p>            
            <?php

            // Beispielcode für ein Textfeld
           // echo '<p style="border-bottom: 1px solid #DFDFDF;"><strong>' . __('Textarea:', $this->var_sTextdomain) . '</strong></p>';
           // echo '<p><span style="display:inline-block;">' . __('Write some text here ...', $this->var_sTextdomain) . '</span><textarea style="width:100%;" id="' . $this->get_field_id('my-widget-text') . '" rows="10" name="' . $this->get_field_name('my-widget-text') . '">' . $instance['my-widget-text'] . '</textarea></p>';
           // echo '<p style="clear:both;"></p>';
        } // END function form($instance)

        /**
         * Widgeteinstellungen in die Datenbank schreiben.
         *
         * @see WP_Widget::update()
         */
        public function update($new_instance, $old_instance) {
            $instance = $old_instance;

            /**
             * Standardwerte setzen
             *
             * @var array
             */
            $new_instance = wp_parse_args((array) $new_instance, array(
                'footer-books-title' => '',
                'footer-books-start' => '0',
                'footer-books-ende' => '5'
            ));

            /**
             * Die über das Formular getätigten Eingaben auf Richtigkeit und Schadcode prüfen
             *
             * @var array
             */
            $instance['footer-books-title'] = (string) strip_tags($new_instance['footer-books-title']);
            $instance['footer-books-start'] = (string) strip_tags($new_instance['footer-books-start']);
            $instance['footer-books-ende'] = (string) strip_tags($new_instance['footer-books-ende']);

            /**
             * Nun kann ein Array mit den Einstellungen an die verarbeitende Funktion
             * zurückgeliefert werden (Klasse WP_Widget). Die Einstellungen werden in der WP-Datenbank
             * gespeichert.
             */
            return $instance;
        } // END function update($new_instance, $old_instance)

        /**
         * Ausgabe des Widgets im Frontend.
         *
         * @see WP_Widget::widget()
         */
        public function widget($args, $instance) {
            extract($args);

            echo $before_widget;

            $title = (empty($instance['footer-books-title'])) ? '' : apply_filters('footer_books_title', $instance['footer-books-title']);

            if(!empty($title)) {
                echo $before_title . $title . $after_title;
            } // END if(!empty($title))

            // HIER nur sinnloser Beispielcode
            // Bereich für die eigentliche Tätigkeit des Widgets
            global $wpdb;

            //Beispiel für ein SQL-Statement
            $results = $wpdb->get_results("
                SELECT a.post_name, post_title
                FROM `wp_posts` AS a
                WHERE a.post_status = 'publish'
                ORDER BY post_date DESC
                LIMIT ".$instance['footer-books-start'].",".$instance['footer-books-ende']
            );

            $output = '<ul>';

            foreach($results as $row)
            {
                //Ausgabe von $row->post_name
            }                

            echo $output . '</ul>';

            echo $after_widget;
        } // END function widget($args, $instance)

        /**
         * HTML des Widgets
         *
         * @param array $args
         */
        private function my_widget_html_output($args = array()) {
            /**
             * Widgetausgabe
             * Hier wird nun das HTML für das Widget erstellt
             */
            $var_sWidetHTML = wpautop($args['my-widget-text'], true);

            return $var_sWidetHTML;
        } // private function my_widget_html_output($args = array())
    } // END class My_Test_Widget extends WP_Widget

    /**
     * Widget initialisieren.
     */
    add_action('widgets_init', create_function('', 'return register_widget("My_Test_Widget");'));
} // END if(!class_exists('My_Test_Widget'))

Schreibe einen Kommentar