Archiv der Kategorie: Widgets

Sag niemals nie: Widget für die X neuesten Beiträge eigener Post Types

Ich hab ja gesagt, mir ist das zu kompliziert, aber jetzt hab ich mir doch ein Widget geschrieben, das die X neuesten Beiträge eines wählbaren Post Types anzeigt. Man kann dem Widget einen Titel geben, man kann eingeben wieviele Beiträge angezeigt werden sollen, man kann auch noch anwählen ob das Datum mit angezeigt werden soll oder nicht. Aussehen tut das Ganze so:

post_type_widget

post_type_widget

Und die Ausgabe in der Sidebar sieht zum Beispiel so aus:

widget_posts

widget_posts

Hier hab ich als Post Type „post“ angegeben (das sind meine Rezepte), das Limit auf 5 gesetzt und Datum ausgeben angekreuzt.

Das Widget wird ganz normal im Plugins-Verzeichnis angelegt, der Header mit der Klassendeklaration sieht so aus:

/*
Plugin Name: Post Type Widget
Plugin URI: http://evileu.de/wordpress
Description: Zeigt die neuesten X Beiträge des gewählten Post Types an
Author: Evi Leu
Version: 1.0
Author URI: http://evileu.de
*/


class PostTypeWidget extends WP_Widget
{
  function PostTypeWidget()
  {
    $widget_ops = array('classname' => 'PostTypeWidget', 'description' => 'Zeigt die neuesten X Beiträge des gewählten Post Types an' );
    $this->WP_Widget('PostTypeWidget', 'Post Type', $widget_ops);
  }

Interessant wird es in der Formulardefinition, da habe ich mir ein Dropdownfeld mit meinen vorhandenen Post Types gebastelt, ich picke das mal heraus und markiere die anzupassenden Stellen rot:

<p>
    <label for="<?php echo $this->get_field_id( 'posttype' ); ?>"><?php _e( 'Select Post Type', 'textdomain' ); ?>:</label>
    <p>Post Type auswählen
   <select id="<?php echo $this->get_field_id('posttype'); ?>" name="<?php echo $this->get_field_name('posttype'); ?>" class="widefat" style="width:100%;">
    <option <?php selected( $instance['posttype'], 'post'); ?> value="post">Post</option>
    <option <?php selected( $instance['posttype'], 'kochbuch'); ?> value="kochbuch">Kochbuch</option>   
    <option <?php selected( $instance['posttype'], 'projects'); ?> value="projects">Projects</option> 
    </select>
   </p>

Man hätte auch die vorhandenen Post Types aus der Datenbank fischen können, aber das war mit zu viel Heckmeck, da müsste man ja noch die WordPress-eigenen Types und evtl. auch die von irgendwelchen Plugins angelegten herausfiltern, ich fand es so herum entschieden einfacher. Wer mehr Post Types hat, ergänzt einfach den Select entsprechend.

Nachtrag: alle Post Types aus der wp_posts anzeigen

Jetzt hab ichs doch noch ausprobiert, wer sich alle vorhandenen Post Types aus der wp_posts im Dropdownfeld anzeigen lassen will, kann für den Select folgende Konstruktion verwenden:

 <p>Post Type auswählen
   <select id="<?php echo $this->get_field_id('posttype'); ?>" name="<?php echo $this->get_field_name('posttype'); ?>" class="widefat" style="width:100%;">
    <?php
    global $wpdb;
    $alleposts = $wpdb->get_results( "SELECT DISTINCT post_type 
                                      from ".$wpdb->prefix."posts");
    
    foreach($alleposts as $einpost){      
      echo "<option ".selected( $instance['posttype'], $einpost->post_type)." value=".$einpost->post_type.">".$einpost->post_type."</option>";
    }
    ?>
    
    </select>
   </p>

Da kriegt man halt auch jeden Schrott angezeigt, aber es funktioniert:

alle_post_types

alle_post_types

Bleibt jedem selber überlassen, ob er diese Option verwenden will oder den statischen Select von oben. Mir ist die statische Dropdownliste lieber, weil sie den Benutzer nicht in Versuchung bringt hier eine sinnfreie Option wie z.B revisions anzuwählen. Natürlich könnte man den SQL entsprechend aufblasen und noch einige „WHERE post_type NOT LIKE ‚xyz'“ dranflicken, aber das ist mir entschieden zu umständlich.

Die Checkbox für das Datum

Für die Checkbox zum Datum anzeigen habe ich folgende Konstruktion verwendet:

<p>
    <input class="checkbox" type="checkbox" <?php checked( $instance[ 'your_checkbox_var' ], 'on' ); ?> id="<?php echo $this->get_field_id( 'your_checkbox_var' ); ?>" name="<?php echo $this->get_field_name( 'your_checkbox_var' ); ?>" /> 
    <label for="<?php echo $this->get_field_id( 'your_checkbox_var' ); ?>">Datum anzeigen</label>
</p>

Die ganze Funktion form($instance) sieht so aus:

function form($instance)
  {
    $instance = wp_parse_args( (array) $instance, array( 'title' => '' ) );
    $title = $instance['title'];
    
    $instance = wp_parse_args( (array) $instance, array( 'posttype' => '' ) );
    $posttype = $instance['posttype'];
    
    $instance = wp_parse_args( (array) $instance, array( 'anzahl' => '' ) );
    $anzahl = $instance['anzahl'];
    
    $instance = wp_parse_args( (array) $instance, array( 'your_checkbox_var' => '' ) );
    $your_checkbox_var = $instance['your_checkbox_var'];
    
    
    
?>
  <p><label for="<?php echo $this->get_field_id('title'); ?>">Titel: <input class="widefat" id="<?php echo $this->get_field_id('title'); ?>" name="<?php echo $this->get_field_name('title'); ?>" type="text" value="<?php echo attribute_escape($title); ?>" /></label></p>
  
   <p>
    <label for="<?php echo $this->get_field_id( 'posttype' ); ?>"><?php _e( 'Select Post Type', 'textdomain' ); ?>:</label>
    <p>Post Type auswählen
   <select id="<?php echo $this->get_field_id('posttype'); ?>" name="<?php echo $this->get_field_name('posttype'); ?>" class="widefat" style="width:100%;">
    <option <?php selected( $instance['posttype'], 'post'); ?> value="post">Post</option>
    <option <?php selected( $instance['posttype'], 'kochbuch'); ?> value="kochbuch">Kochbuch</option>   
    <option <?php selected( $instance['posttype'], 'projects'); ?> value="projects">Projects</option> 
    </select>
   </p>
  <p><label for="<?php echo $this->get_field_id('anzahl'); ?>">Anzahl: <input id="<?php echo $this->get_field_id('anzahl'); ?>" 
name="<?php echo $this->get_field_name('anzahl'); ?>" type="number" value="<?php echo attribute_escape($anzahl); ?>" /></label></p>
<p>
    <input class="checkbox" type="checkbox" <?php checked( $instance[ 'your_checkbox_var' ], 'on' ); ?> id="<?php echo $this->get_field_id( 'your_checkbox_var' ); ?>" name="<?php echo $this->get_field_name( 'your_checkbox_var' ); ?>" /> 
    <label for="<?php echo $this->get_field_id( 'your_checkbox_var' ); ?>">Datum anzeigen</label>
</p>
  
  
  
<?php
  }

Dann noch die Funktion update() anpassen:

function update($new_instance, $old_instance)
  {
    $instance = $old_instance;
    $instance['title'] = $new_instance['title'];
    $instance['posttype'] = $new_instance['posttype'];
    $instance['anzahl'] = $new_instance['anzahl'];
    $instance[ 'your_checkbox_var' ] = $new_instance[ 'your_checkbox_var' ];
    return $instance;
  }

Und schliesslich in der Funktion widget() die Variablen abholen:

function widget($args, $instance)
  {
    extract($args, EXTR_SKIP);
 
    echo $before_widget;
    $your_checkbox_var = $instance[ 'your_checkbox_var' ] ? 'true' : 'false';
    $title = empty($instance['title']) ? ' ' : apply_filters('widget_title', $instance['title']);
    $posttype    = empty( $instance['posttype'] ) ? '' : esc_attr( $instance['posttype'] );
    $anzahl    = empty( $instance['anzahl'] ) ? '' : esc_attr( $instance['anzahl'] );

Der eigentliche OpCode des Widgets ist nicht weiter kompliziert, die Hauptsache ist die SQL-Query, in die ich die Variablen für den Post Type und für die Anzahl einsetze:

global $wpdb;
    $alleposts = $wpdb->get_results( "SELECT * from ".$wpdb->prefix."posts 
where post_type like '".$posttype."' 
and post_status like 'publish' 
ORDER BY post_date DESC
 LIMIT ".$anzahl."");
    

Das ganze wird noch nach dem post_status=publish gefiltert und absteigend nach Datum sortiert und kann jetzt in einem foreach ausgegeben werden. Dabei baue ich noch die Abfrage ein, ob das Datum mit ausgegeben werden soll:

foreach($alleposts as $einpost){
        
        $dt = new DateTime($einpost->post_date);
        echo $einpost->post_title." ";
        if ($your_checkbox_var == 'true'){ echo $dt->format('d.m.Y');}
        echo "<br>";
    }

Hier könnte man wie schon öfter gehabt mit dem get_permalink() über die ID gleich noch den Link zum entsprechenden Beitrag mit einbauen, das spare ich mir jetzt. Wem das jetzt zu schnell ging, den ganzen Code des Widgets gibt es hier gezippt: post-type-widget

Viel Spaß beim Nachbauen!

 

 

Custom Post Types in einem Widget

Ich hab nach langem und nicht besonders produktiven Googlen beschlossen, KEIN eigenes Widget für die Ausgabe der neuesten X Kochbücher zu schreiben, das ist mir viel zu umständlich. Es gibt auch Plugins speziell für diesen Zweck, aber das muss auch nicht sein, denn eigentlich ist die Anforderung mit einem einzigen MySQL-Statement zu erschlagen, das machen wir selber. Ich packe das wieder mal in einen Shortcode, der kann in die functions.php oder in ein Plugin, ganz nach Belieben. Das Ganze sieht schlicht und ergreifend so aus:

function kochbuch_ausgabe(){
   
  global $wpdb;
  $alleposts = $wpdb->get_results( "SELECT * from iii_wpposts 
WHERE post_type LIKE 'kochbuch' 
AND post_status LIKE 'publish' 
ORDER BY post_date DESC LIMIT 10");
    
    $ausgabe="";
    foreach($alleposts as $einpost){
        
        $ausgabe = $ausgabe.$einpost->post_title."</br>";
    }
    return $ausgabe;
 }
 add_shortcode('k_ausgabe', 'kochbuch_ausgabe');

Im Select ist alles drin was wir brauchen, das Limit kann man sich nach Wunsch selber anpassen.

Wenn wir das jetzt in einem Widget in der Sidebar haben wollen, klemmen wir uns ein Text-Widget und fügen da den Shortcode ein, und vergeben einen Titel nach Wunsch. Sollte das nicht klappen, muss man zuerst noch Shortcodes für das Text-Widget aktivieren, das geht mit einer Zeile in der functions.php:

add_filter('widget_text', 'do_shortcode');

Fertig sieht das so aus:

die_neuesten_kochbücher

die_neuesten_kochbücher

Wer mag, kann sich jetzt noch mit get_the_permalink() die Links zu den entsprechenden Kochbüchern basteln, die ID ist ja mit im Select. Das spare ich mir jetzt, da kann jeder selber kreativ werden.

Die Ausgabe der Custom Taxonomies in einem Widget: ein schickes kleines Plugin

Da mir die Tabellenstruktur der Taxonomies zu komplex für einen Select ist (join über 4 Tabellen), hab ich mal kurzen Prozeß gemacht und mir ein Plugin für diesen Zweck ausgesucht:

List Custom Taxonomy Widget

Es tut genau das, was es soll, und ist so gut wie selbsterklärend.

list_custom_taxonomy

list_custom_taxonomy

Die Ausgabe ist ganz wie erwartet:

aus_aller_welt

aus_aller_welt

Damit lass ich es gut sein, da muss man echt nichts mehr selber programmieren. Das Widget läßt sich natürlich auch für die Kochbuch-Stichworte verwenden, da brauchen wir also auch nix extra.

widget_stichworte

widget_stichworte

Für Bastler: es geht auch mit get_terms()

Wer sich die Ausgabe der Custom Taxonomies partout selber antun möchte, kann auf die WP_Funktion get_terms() zurückgreifen (siehe Codex). Den Link auf die enstprechenden Begriffe holt man sich dabei mit get_term_link(). Ich hab hier nur mal ein ganz kurzes Beispiel in einen Shortcode gepackt:

function get_land(){
 $terms = get_terms( 'land' );
if ( ! empty( $terms ) && ! is_wp_error( $terms ) ){
 
 foreach ( $terms as $term ) {
   
   echo "<a href = '".get_term_link($term)."'>".$term->name ."</a><br>";
     }
 
}
}
add_shortcode('land_ausgabe', 'get_land');

Das berücksichtigt jetzt nicht die geschachtelte Struktur, sondern gibt nur eine alphabetisch sortierte Liste der Terms der Taxonomie land mit ihren Links aus.

land_bastler

land_bastler

Man könnte jetzt noch den Namen der Taxonomie als Parameter in den Shortcode übergeben und sonst noch allerhand… aber wie gesagt, das ist was für Bastler. Ich verwende das oben vorgestellte Plugin, und gut ists.

Rezeptecounter: so wird ein Widget draus

Wie man in WordPress ein eigenes Widget erstellt, habe ich in diesem Beitrag: Widget-Basteln macht Spaß schon mal ausführlich vorgestellt, deswegen machen wir das hier im Schnelldurchgang. Der Code läßt sich relativ leicht auf die Anforderungen für die Rezepthitparade anpassen. Wir brauchen zwei Eingabefelder, eines für den Titel des Widgets, und eins für die auszugebende Anzahl an Rezepten. In den OpCode des Widgets kommt unsere Ausgabelogik, die können wir 1:1 aus dem vorigen Beitrag übernehmen.

Nur kurz zur Erinnerung: Widgets werden von der Struktur her genau wie Plugins in einer eigenen PHP-Datei angelegt, die kommt auch ins Plugins-Verzeichnis. Hier mal der Code ohne die Ausgabefunktionalität:

<?php
/*
Plugin Name: Hitparaden Widget
Plugin URI: http://evileu.de/wordpress
Description: Gibt die am öftesten aufgerufenen Rezepte aus, Anzahl vom Benutzer wählbar
Author: Evi Leu
Version: 1.0
Author URI: http://evileu.de
*/


class HitparadenWidget extends WP_Widget
{
  function HitparadenWidget()
  {
    $widget_ops = array('classname' => 'HitparadenWidget', 'description' => 'Zeigt die am öftesten aufgerufenen Rezepte an' );
    $this->WP_Widget('HitparadenWidget', 'Hitparade', $widget_ops);
  }
 
  function form($instance)
  {
    $instance = wp_parse_args( (array) $instance, array( 'title' => '' ) );
    $title = $instance['title'];
        
    $instance = wp_parse_args( (array) $instance, array( 'anzahl' => '' ) );
    $anzahl = $instance['anzahl'];
    
    
?>
  <p><label for="<?php echo $this->get_field_id('title'); ?>">Titel: <input class="widefat" id="<?php echo $this->get_field_id('title'); ?>" name="<?php echo $this->get_field_name('title'); ?>" type="text" value="<?php echo attribute_escape($title); ?>" /></label></p>
  
  <p><label for="<?php echo $this->get_field_id('anzahl'); ?>">Anzahl: <input id="<?php echo $this->get_field_id('anzahl'); ?>" 
name="<?php echo $this->get_field_name('anzahl'); ?>" type="number" value="<?php echo attribute_escape($anzahl); ?>" /></label></p>
  
  
<?php
  }
 
  function update($new_instance, $old_instance)
  {
    $instance = $old_instance;
    $instance['title'] = $new_instance['title'];
    $instance['anzahl'] = $new_instance['anzahl'];
    return $instance;
  }
 
  function widget($args, $instance)
  {
    extract($args, EXTR_SKIP);
 
    echo $before_widget;
    
    $title = empty($instance['title']) ? ' ' : apply_filters('widget_title', $instance['title']);
    $anzahl    = empty( $instance['anzahl'] ) ? '' : esc_attr( $instance['anzahl'] );
   
    // WIDGET CODE GOES HERE
    /**********************/    
    //END WIDGET CODE
    
    echo $after_widget;
  }
 
}
add_action( 'widgets_init', create_function('', 'return register_widget("HitparadenWidget");') );?>

Das ist das Gerippe für das Widget, es werden zwei Eingabefelder erzeugt und deren Werte auf die Variablen $title und $anzahl gelegt. Mit denen kann man weiterarbeiten, hier kommt der Code aus dem vorigen Beitrag nahezu unverändert rein:

// WIDGET CODE GOES HERE
    echo "<h2>".$title."</h2>";
    echo "<h3>Die ".$anzahl." beliebtesten Rezepte</h3>"; 
    
        //Bisher gespeicherte Rezepte holen
    global $wpdb;
        $alleposts = $wpdb->get_results( "SELECT * from wp_options where option_name like 'zaehler_%'");
        
        
        $rohdaten = array();
        $i=0;
        foreach($alleposts as $einpost){
            
            //Optionswerte auslesen            
            $meineOption = get_option($einpost->option_name);
            $o_zaehler = $meineOption['zaehler'];
            $o_titel = $meineOption['titel'];
            $o_id = $meineOption['id'];
            //debug unsortierte Ausgabe
            //echo $o_titel." ".$o_zaehler."<br>";
            
            //Array befüllen
            $rohdaten[$i]['zaehler']= $o_zaehler;
            $rohdaten[$i]['titel']= $o_titel;
            $rohdaten[$i]['id']= $o_id;
            $i=$i+1;
        }
        //echo "<h2>Hitparade:</h2>";
    
        $counter = array();
        foreach ($rohdaten as $key => $row)
        {
            $counter[$key] = $row['zaehler'];
        }
        array_multisort($counter, SORT_DESC, $rohdaten);


        $hilf = array_slice($rohdaten, 0, $anzahl);
        foreach($hilf as $roh){
                
                    echo $roh['titel']." (".$roh['zaehler'].")<br>";
                    
            }

    
    //END WIDGET CODE

Ich verwende nur noch den $title für die Überschrift des Widgets und die $anzahl für den array_slice, um die Anzahl der ausgegebenen Datensätze zu begrenzen. Das wars auch schon! Nach erfolgreicher Aktivierung präsentiert sich das Widget so:

hitparadenwidget

hitparadenwidget

Die Ausgabe sieht so aus:

hitparade_ausgabe

hitparade_ausgabe

Funkt, kann man so lassen.

 

Noch mehr Widget-Bastelei: ein eigenes Dropdown-Feld

Ich hab im vorigen Artikel etwas geschummelt und mir ein fertiges Konstrukt für das Dropdown-Feld mit den Kategorien ergooglet, das ging so:

<p>
    <label for="<?php echo $this->get_field_id( 'select' ); ?>">Kategorie auswählen:</label>
    <?php wp_dropdown_categories( array( 'show_option_none' =>' ','name' => $this->get_field_name( 'select' ), 'selected' => $select ) ); ?>
  </p>

Wer unbedingt genaueres dazu wissen möchte, kanns im Codex bei wp_dropdown_categories nachschauen, ich spar mir das, weil es der volle Overkill mit ungefähr 20 Parametern ist, und die Source-Beispiele auch nicht gerade zur Erhellung beitragen.

Dropdown-Felder in Widgets braucht man aber immer wieder, und ich stelle hier eine realtiv einfache Methode vor, wie man sie sich selbst zusammenbastelt.

Das Anwendungsbeispiel

Ich möchte im Widget ein Dropdown-Feld haben, in dem man einen Post Type wählen kann, die Optionen sollen Post, Page und Custom Type heissen. Dazu erweitern wir den Widget-Code aus dem vorigen Artikel um ein Feld namens „posttype“, ich markiere hier mal in rot wo man da überall eingreifen muss:

    function form($instance)
  {
    $instance = wp_parse_args( (array) $instance, array( 'title' => '' ) );
    $title = $instance['title'];
    
    $instance = wp_parse_args( (array) $instance, array( 'posttype' => '' ) );
    $select = $instance['posttype'];
?>
  <p><label for="<?php echo $this->get_field_id('title'); ?>">Titel: <input class="widefat" id="<?php echo $this->get_field_id('title'); ?>" name="<?php echo $this->get_field_name('title'); ?>" type="text" value="<?php echo attribute_escape($title); ?>" /></label></p>
  
   <--! HIER KOMMT DAS DROPDOWN HIN-->
   
       
<?php
  }
 function update($new_instance, $old_instance)
  {
    $instance = $old_instance;
    
    $instance['title'] = $new_instance['title'];
    $instance['posttype'] = $new_instance['posttype'];
    
    return $instance;
  }

Dann kommt in die function form() folgende Konstruktion für das Dropdown-Feld, ich markiere grün wo man da eigene Werte einträgt:

<p>Post Type auswählen
   <select id="<?php echo $this->get_field_id('posttype'); ?>" name="<?php echo $this->get_field_name('posttype'); ?>" class="widefat" style="width:100%;">
    <option <?php selected( $instance['posttype'], 'Post'); ?> value="Post">Post</option>
    <option <?php selected( $instance['posttype'], 'Page'); ?> value="Page">Page</option> 
    <option <?php selected( $instance['posttype'], 'Custom Type'); ?> value="Custom Type">Custom Type</option>   
    </select>
   </p>

Das erzeugt uns im Widget das Dropdown-Feld mit den drei möglichen Werten:

dropdown_drei_werte

dropdown_drei_werte

Für die Ausgabe modifizieren wir jetzt nur noch die function widget() ein bisschen:

 function widget($args, $instance)
  {
    extract($args, EXTR_SKIP);
 
    echo $before_widget;
    
    $title = $instance['title'];
    $posttype = $instance['posttype'];
     
    // WIDGET CODE KOMMT HIERHIN
    echo "<h3>".$title."</h3>";
    
    echo "Post Type= ".$posttype."<br>";
    
    echo $after_widget;
  }

Fertig! Ausgabe:

posttype_ausgabe

posttype_ausgabe

Nicht besonders spektakulär, aber ausbaufähig. Ich denke, das kann man immer wieder mal brauchen, wenn der User aus einer vorgegebenen Liste eine Auswahl treffen soll.

Kleine Ergänzung: ein numerisches Feld geht auch

Das geht ganz einfach, indem man den type des Textinput-Felds auf number stellt, der Rest bleibt wie vorher:

<p><label for="<?php echo $this->get_field_id('anzahl'); ?>">Anzahl: <input id="<?php echo $this->get_field_id('anzahl'); ?>" 
name="<?php echo $this->get_field_name('anzahl'); ?>" type="number" value="<?php echo attribute_escape($anzahl); ?>" /></label></p>

Schon klappts:

numerisch

numerisch

 

Widget-Basteln macht Spaß: ein Widget mit Benutzereingaben

Das, so gebe ich ehrlich zu, ist zusammengeklaut und abgekupfert und herausgegooglet. Da aber das Widgetbasteln in WordPress erstens Spaß macht und zweitens vielfältige Einsatzmöglichkeiten bietet, beschreibe ich hier doch mal recht ausführlich meinen Weg zum eigenen Widget mit Benutzereingaben. Das Meiste hab ich aus dieser Anleitung hier bei makuseof.com gelernt, da wird einem das funktionale Gerippe eines WordPress-Widgets vorgelegt. Ebenfalls sehr aufschlussreich ist diese Anleitung hier bei wpmudev.

Die Vorgabe: ein Featured Category Widget

Ich hab mir eine relativ einfach Aufgabe gestellt. Mein Widget soll ausgeben, wieviele Rezepte bisher veröffentlich wurden, und dann soll man noch eine Featured Category anwählen können, für die dann ebenfalls die Anzahl der Rezepte ausgegeben wird, also so in der Art:

Rezepte insgesamt 317

56 davon Vegetarisch

Dann hätte ich noch gern einen frei wählbaren Titel für das Widget. Das hört sich simpel an, war aber in der Realisieung nicht ohne, nicht zuletzt weil der Codex zu den Widget-Funktionalitäten sehr lückenhaft und umständlich ist. Aber wir fangen mal ganz vorne an, und sehen wie weit wir kommen.

Anlegen der Widget-Datei

Man erzeugt im Plugins-Verzeichnis seiner WordPress-Installation ein neues php-File mit dem Namen des Widgets, z. B. mein-tolles-widget.php. Die kriegt jetzt erstmal den klassischen Plugin-Header:

/*
Plugin Name: Top Category Widget
Plugin URI: http://evileu.de/wordpress
Description: Gibt die Gesamtzahl der veröffentlichten Rezepte und die Anzahl der Beiträge einer frei wählbaren Kategorie an
Author: Evi Leu
Version: 1.0
Author URI: http://evileu.de
*/

Dann passiert Folgendes:

class FeaturedCategoryWidget extends WP_Widget
{
  function FeaturedCategoryWidget()
  {
    $widget_ops = array('classname' => 'FeaturedCategoryWidget', 'description' => 'Zeigt die Anzahl der Rezepte einer frei wählbaren Kategorie an' );
    $this->WP_Widget('FeaturedCategoryWidget', 'Featured Kategorie', $widget_ops);
  }

Eine neue Instanz der Klasse WP_Widget wird angelegt und mit unseren eigenen Benennungen versehen, ich hab die mal fett und rot markiert. Dann kommt noch etliches andere, was später erklärt wird, und am Ende der Datei wird noch per add_action das Widget aktiviert:

add_action( 'widgets_init', create_function('', 'return register_widget("FeaturedCategoryWidget");') );?>

Das reicht aus, damit das Testwidget in den zur Verfügung stehenden Plugins angezeigt wird und aktiviert werden kann. Macht aber noch keinen Sinn, es tut ja noch nichts.

Das Formular für die Benutzereingaben

Dafür brauchts eine Funktion namens form($instance), die sieht so aus, meine Ergänzungen in rot:

 function form($instance)
  {
    $instance = wp_parse_args( (array) $instance, array( 'title' => '' ) );
    $title = $instance['title'];
    
    $instance = wp_parse_args( (array) $instance, array( 'select' => '' ) );
    $select = $instance['select'];
    
    
?>
  <p><label for="<?php echo $this->get_field_id('title'); ?>">Titel: <input class="widefat" id="<?php echo $this->get_field_id('title'); ?>" name="<?php echo $this->get_field_name('title'); ?>" type="text" value="<?php echo attribute_escape($title); ?>" /></label></p>
  
   <p>
    <label for="<?php echo $this->get_field_id( 'select' ); ?>"><?php _e( 'Select category', 'textdomain' ); ?>:</label>
    <?php wp_dropdown_categories( array( 'show_option_none' =>' ','name' => $this->get_field_name( 'select' ), 'selected' => $select ) ); ?>
  </p>

Damit werden zwei Felder für die Benutzereingaben angelegt. Das erste für den Titel hab ich aus dem Beispiel von makuseof.com übernommen. Das zweite Feld für das Auswahlfeld hab ich mir zusammengegooglet, das stellt eine Dropdown-Liste aller Kategorien zur Verfügung und belegt die Variable $select mit der ID (numerisch) der gewählten Kategorie.

Jetzt kommt noch eine Funktion, die uns die vorher gewählten Werte aus dem Formular zur Verfügung stellt, auch die hab ich einfach übernommen:

function update($new_instance, $old_instance)
  {
    $instance = $old_instance;
    $instance['title'] = $new_instance['title'];
    $instance['select'] = $new_instance['select'];
    return $instance;
  }

Und jetzt kommt endlich die tatsächliche Funktionalität des Widgets. Da werden zuerst noch die beiden Variablen $title und $select gesäubert, aber dann kanns losgehen

function widget($args, $instance)
  {
    extract($args, EXTR_SKIP);
 
    echo $before_widget;
    
    $title = empty($instance['title']) ? ' ' : apply_filters('widget_title', $instance['title']);
    $select    = empty( $instance['select'] ) ? '' : esc_attr( $instance['select'] );
    
   
    // WIDGET CODE KOMMT HIER
    
    
    echo $after_widget;
  }

Der tatsächliche OpCode des Widgets ist sehr straightforward:

echo "<h3>".$title."</h3>";
    echo "Rezepte insgesamt: ".wp_count_posts()->publish."<br>";
    
    global $wpdb;
    $alleposts = $wpdb->get_results( "SELECT * from ".$wpdb->prefix."term_taxonomy where term_id = ".$select."");
    
    foreach($alleposts as $einpost){
        
        echo $einpost->count;
    }
    
    echo " davon ".get_the_category_by_ID($select);

Ich geb erstmal den vom Benutzer eingegebenen Titel als h3 aus, danach die Gesamtzahl der veröffentlichten Posts=Rezepte. Dann kommt eine kleine Datenbankabfrage, ich hol mir aus der wp_term_taxonomy die Anzahl der zur aktuellen Kategorie (ID liegt auf der Variablen $select) vorhandenen Beiträge, die steht da nämlich praktischerweise drin, da muss man nicht lang rummachen. Das wars! Unser Widget hat jetzt ein Eingabefeld für den Titel und eine Dropdownliste zur Auswahl der Kategorie:

widget_mit_dropdown

widget_mit_dropdown

Der Output ist unspektakulär, aber es funktioniert wie geplant:

widget_output

widget_output

Kurzer Blick auf die Datenbank

Wer übrigens wissen möchte, wo die Benutzereingaben gespeichert werden, das ist ein bisschen frustelig. Die werden nämlich serialized abgespeichert, in der wp_options. Sucht da nach einem Eintrag mit dem Namen widget_[name eures widgets]. Im Feld option_value steht dann sowas:

a:2:{i:2;a:2:{s:5:“title“;s:12:“Alle Rezepte“;s:6:“select“;s:2:“29″;}s:12:“_multiwidget“;i:1;}

Der gesamte Code als ZIP

Weil die Schachtelung doch ein wenig kompliziert ist, kommt hier noch der gesamte Code des Widgets als ZIP-Archiv: category-widget

Ein eigenes WordPress-Theme 2: Widget-fähige zweite Sidebar einbinden

Also, das war jetzt einfacher als ich dachte, deswegen kommts hier heute noch rein. Ich hatte ja in meinem dreispaltigen Template ursprünglich eine statische linke Seitenleiste definiert, und mit einer eigenen kleinen Funktion zur Anzeige der 10 neuesten Rezepte gefüllt, das sah in der index.php so aus:

<div id = "sidebar-left">
    
    <h2>Die neuesten Rezepte</h2>
        <ul>
            <?php $liste = wp_get_recent_posts();
            
            foreach($liste as $item){
                echo '<li><a href="' . get_permalink($item["ID"]) . '">' . $item["post_title"].'</a> </li>';
            }    
            ?>
        </ul> 
 
  </div> <!-- sidebar-left-->

Natürlich gibts aber das Widget „Neueste Beiträge“ schon, und das wollen wir auch nutzen, indem wir die linke Sidebar widgetfähig machen.

Eine neue Datei für die linke Sidebar anlegen

Die heißt sidebar-links.php (oder sidebar-xy.php) und enthält folgenden Code:

<div id="sidebar" class="widget-area">
<?php dynamic_sidebar( 'sidebar-2' ); ?>

</div><!-- #sidebar .widget-area -->

Damit WordPress nun auch eine dynamische Sidebar namens sidebar-2 kennt, kommt folgender Eintrag in die functions.php, dabei passt man den name, die id und die description an:

register_sidebar( array (
        'name' => __( 'Linke Sidebar'),
        'id' => 'sidebar-2',
        'description' => __( 'Widgets in der linken Sidebar anordnen.'),
        'before_widget' => '<aside id="%1$s" class="widget %2$s">',
        'after_widget' => "</aside>",
        'before_title' => '<h3 class="widget-title">',
        'after_title' => '</h3>',
    ) );

In der index.php ersetzt man nun den gesamten Code der statischen Sidebar durch den Aufruf:

<div id = "sidebar-left">
    
    <?php get_sidebar('links'); ?>
 
  </div> <!-- sidebar-left-->

Tückisch ist hier das kleine Wörtchen „links“, das muss genauso heissen wie man es oben im Namen der sidebar-links.php (oder sidebar-xy.php) definiert hat.

Das wars aber auch schon, unsere linke Sidebar taucht jetzt in der Widget-Verwaltung auf und kann bestückt werden:

widgets_linke_sidebar

widgets_linke_sidebar

Ein eigenes Widget erstellen: kurz und knackig

Ich habe hier bei blog.unkonsorten.com die ultimative Kurzanleitung zum Erstellen eines eigenen Widgets gefunden, die möchte ich euch nicht vorenthalten( Beim Code kopieren auf die „“ und “ aufpassen, die muss man korrigieren).

Damit es etwas Interessanteres ausgibt als „Hallo Welt“ habe ich mal die Anzahl der veröffentlichten Rezepte eingebaut, die kriegt man so :

function widget_sidebar() {
// Hier kann man eigenen Code einfuegen
echo "<h3>Rezepte insgesamt: ".wp_count_posts()->publish."</h3>";
}

Das wars auch schon – Have fun with Widgets!