In dieser Artikelreihe geht es darum, ein WordPress-Theme zu erstellen – von Grund auf. In Teil 17 geht es um die zwei Widgets, die das Theme mitbringt.
Im letzten Teil hatte ich geschrieben, dass es ab jetzt um den Customizer gehen würde – dabei habe ich allerdings die zwei Widgets vergessen, die das Theme mitbringt. Die müssen vorher besprochen werden, da auch sie mit Customizer-Einstellungen angepasst werden können.
Das Theme bringt wie gesagt zwei Widgets mit – eins zum Anzeigen der neuesten Galerien und eins zum Hervorheben bestimmter Galerien. Um ein Widget zu erstellen, muss eine Unterklasse von WP_Widget
erstellt und darin mindestens die Methoden widget()
, update()
, form()
sowie der Konstruktor genutzt werden. Im Konstruktor werden grundlegende Eigenschaften des Widgets festgelegt, wie dessen Name und Beschreibung. Die widget()
-Methode stellt das Widget im Frontend dar, update()
kümmert sich um die Aktualisierung der Einstellungen im Backend und form()
zeigt das Widget im Widget-Bereich an.
Das Recent-Galleries-Widget
Für die Klassen erstellen wir jeweils eine eigene Datei innerhabl des inc
-Ordners unseres Themes. Das Widget für die neuesten Galerien kommt in die Datei class-recent-galleries.php
.
<?php
/**
* Recent_Galleries widget class
*/
class Bornholm_Recent_Galleries extends WP_Widget {
public function __construct() {
$widget_ops = array(
'classname' => 'widget_recent_galleries',
'description' => _x( 'Your site’s most recent galleries.', 'Description of the recent galleries widget', 'bornholm' )
);
parent::__construct( 'recent-galleries', _x( 'Recent Galleries', 'Name of the recent galleries widget', 'bornholm' ), $widget_ops );
}
Code-Sprache: HTML, XML (xml)
Im Code-Block oben ist der Anfang der Klasse Bornholm_Recent_Galleries
abgebildet, die die WP_Widget
-Klasse erweitert. Über __construct()
wird direkt nach Aufrufen der Klasse ein Array mit dem Klassennamen des Widgets sowie der übersetzbaren Beschreibung erstellt. Im Anschluss wird an den Konstruktor der Oberklasse, also WP_Widget
, als erster Parameter ein Bezeichner für das Widget übergeben. Es folgt der Name des Widgets sowie die Optionen aus dem Array.
public function widget( $args, $instance ) {
$title = apply_filters( 'widget_title', empty( $instance['title'] ) ? '' : $instance['title'], $instance, $this->id_base );
$number = ( ! empty( $instance['number'] ) ) ? absint( $instance['number'] ) : 2;
if ( ! $number ) {
$number = 2;
}
/**
* Filter the arguments for the Recent Galleries widget
*
* @see WP_Query::get_posts()
*
* @param array $args An array of arguments used to retrieve the recent posts.
*/
$result = new WP_Query( apply_filters( 'widget_galleries_args', array(
'posts_per_page' => $number,
'no_found_rows' => true,
'post_status' => 'publish',
'ignore_sticky_posts' => true,
'tax_query' => array(
array(
'taxonomy' => 'post_format',
'field' => 'slug',
'terms' => 'post-format-gallery'
)
)
) ) );
if ( $result->have_posts() ) {
echo $args['before_widget'];
if ( $title ) {
echo $args['before_title'] . $title . $args['after_title'];
}
while ( $result->have_posts() ) {
$result->the_post();
$post = get_post( get_the_ID() );
$images = bornholm_get_gallery_images( $post->ID );
if ( $images ) { ?>
<div>
<?php bornholm_gallery_header( 'h4', $images, 'thumbnail', $post ); ?>
</div>
<?php }
}
echo $args['after_widget'];
// Reset the global $the_post as this query will have stomped on it
wp_reset_postdata();
}
}
Code-Sprache: PHP (php)
Innerhalb der widget()
-Methode, der Argumente von der Sidebar sowie die aktuelle Instanz des Widgets übergeben werden, wird zuerst der Titel des Widgets der $title
-Variable zugewiesen. Diese Anwendung des Filters ist leicht angepasst aus einem der Core-Widgets übernommen. Falls kein Titel eingetragen wurde, wird ein leerer String gespeichert. Im nächsten Schritt holen wir uns aus $instance['number']
die Anzahl, die angezeigt werden soll. Ist nichts eingetragen, setzen wir den Wert auf 2
.
Als nächstes müssen wir uns die neuesten Beiträge mit dem Post-Format „Galerie“ holen, und starten dafür eine neue WP_Query
. Innerhalb des Argument-Arrays geben wir für posts_per_page
die Anzahl aus $number
an. Mit dem Wert true
für no_found_rows
geben wir an, dass WordPress die gefundenen Datenbankzeilen nicht zählen soll, was die Performance verbessert aber wohl nur funktioniert, wenn keine Pagination eingesetzt wird. Die Beiträge sollen des Weiteren veröffentlicht sein und Sticky-Posts ignoriert werden. Für tax_query
geben wir das bereits bekannte Array an, um nur Beiträge des Galerie-Post-Formats zu bekommen.
Wenn wir im Ergebnis Beiträge haben, dann geben wir mit $args['before_widget']
das Markup aus, das in der register_sidebar()-Funktion von der Sidebar, in der das Widget angezeigt wird, für before_widget
eingetragen wurde. Das sah beispielsweise für eine Sidebar so aus:
register_sidebar( array(
'name' => 'Sidebar',
'id' => 'sidebar-1',
'description' => '',
'before_widget' => '<div class="widget clearfix %2$s">',
'after_widget' => '</div>',
'before_title' => '<h3 class="widget-title">',
'after_title' => '</h3>'
) );
Code-Sprache: PHP (php)
Wenn ein Titel vergeben wurde, umschließen wir ihn mit dem Markup aus der entsprechenden register_sidebar()
-Funktion und geben ihn aus. Danach starten wir eine Schleife und holen uns die ID des aktuellen Beitrags. Damit können wir uns die Bilder aus der Funktion bornholm_get_gallery_images()
holen und das erste mit dem Titel durch die ebenfalls bereits besprochene Funktion bornholm_gallery_header()
ausgeben. Nach der Schleife wird das Markup für nach dem Widget ausgegeben und die Postdaten zurückgesetzt.
public function update( $new_instance, $old_instance ) {
$instance = $old_instance;
$instance['title'] = strip_tags( $new_instance['title'] );
$instance['number'] = (int) $new_instance['number'];
return $instance;
}
Code-Sprache: PHP (php)
Die update()
-Methode ist relativ kurz. Hier werden nach dem Speichern des Nutzers im Backend die alte Widget-Werte gegen die Neuen ausgetauscht. Als Parameter bekommt die Methode die neue und alte Instanz des Widgets übergeben. Zuerst wird der Variable $instance
die alte Instanz zugewiesen. Anschließend werden die Schlüssel des Arrays mit den neuen Werten überschrieben, für die gleichzeitig sichergestellt wird, dass sie einen sinnvollen Wert enthalten. Danach wird die neue Instanz zurückgegeben.
public function form( $instance ) {
$title = isset( $instance['title'] ) ? esc_attr( $instance['title'] ) : '';
$number = isset( $instance['number'] ) ? absint( $instance['number'] ) : 2;
?>
<p><label for="<?php echo $this->get_field_id( 'title' ); ?>"><?php _e( 'Title:', 'bornholm' ); ?></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 $title; ?>"/>
</p>
<p><label
for="<?php echo $this->get_field_id( 'number' ); ?>"><?php _e( 'Number of galleries to show:', 'bornholm' ); ?></label>
<input class="widefat" id="<?php echo $this->get_field_id( 'number' ); ?>"
name="<?php echo $this->get_field_name( 'number' ); ?>" type="number"
value="<?php echo $number; ?>"/></p>
<?php
}
}
Code-Sprache: JavaScript (javascript)
Mit form()
wird das Formular ausgegeben, das im Backend angezeigt wird. Als Parameter bekommt es die aktuelle Instanz des Widgets. Zuerst wird geprüft, ob Titel und Anzahl gesetzt sind, sonst werden die Standard-Werte eingesetzt. Anschließend wird für den Titel ein einfaches Textfeld erstellt. Um das id
-Attribut und somit auch das for
-Attribut des label-Elements zu erstellen, soll die get_field_id()
-Methode eingesetzt werden, der der Name des Feldes übergeben wird. Über diesen Namen kann in den anderen Methoden auf den Wert zugegriffen werden, beispielsweise in update()
mit $new_instance['title']
.
Um das name
-Attribut zu erstellen, soll die Methode get_field_name()
genutzt werden. Die widefat
-Klasse wird von WordPress für Widgets genutzt und damit gleich gestylt. Als value
geben wir den eventuell eingetragenen Titel aus. Nach demselben Prinzip wird für das Eingabefeld der Anzahl vorgegangen, nur dass hier als type
der Wert number
angegeben wird. Anschließend ist das Widget fertig und kann genutzt werden.
Das Featured-Galleries-Widget
Um bestimmte Galerien in der Sidebar anzeigen zu können, wird der Nutzer die IDs der jeweiligen Beiträge eintragen müssen. Das ist zwar nicht die allerschönste Lösung, damit kann der Nutzer aber unter anderem auch selbst über die Sortierung der Ausgabe entscheiden. Das Widget gehört in die class-featured-galleries.php
im inc
-Ordner und fängt so an:
<?php
/**
* Featured_Galleries widget class
*/
class Bornholm_Featured_Galleries extends WP_Widget {
public function __construct() {
$widget_ops = array(
'classname' => 'widget_featured_galleries',
'description' => _x( 'Enter ids of galleries you want to feature.', 'Description of the featured galleries widget', 'bornholm' )
);
parent::__construct( 'featured-galleries', _x( 'Featured Galleries', 'Name of the featured galleries widget', 'bornholm' ), $widget_ops );
}
Code-Sprache: HTML, XML (xml)
Der Konstruktor kümmert sich wieder um den Klassennamen, die Beschreibung sowie den Titel – nichts Neues also.
public function widget( $args, $instance ) {
$title = apply_filters( 'widget_title', empty( $instance['title'] ) ? '' : $instance['title'], $instance, $this->id_base );
$gallery_ids = ! empty( $instance['gallery_ids'] ) ? explode( ',', $instance['gallery_ids'] ) : array();
$counter = 0;
foreach ( $gallery_ids as $gallery_id ) {
$post = get_post( $gallery_id );
$format = get_post_format( $gallery_id );
if ( $post && $format == 'gallery' ) {
if ( $counter == 0 ) {
echo $args['before_widget'];
if ( $title ) {
echo $args['before_title'] . $title . $args['after_title'];
}
}
$images = bornholm_get_gallery_images( $gallery_id ); ?>
<div>
<?php bornholm_gallery_header( 'h4', $images, 'thumbnail', $post ); ?>
</div>
<?php $counter ++;
}
}
if ( $counter != 0 ) {
echo $args['after_widget'];
}
}
Code-Sprache: PHP (php)
Erneut wird in widget()
zuerst der Titel ermittelt. Anschließend werden die eingegebenen IDs aus dem Widget geholt. Da wir diese getrennt als Array benötigen und die IDs im Eingabefeld durch Komma getrennt werden sollen, müssen wir sie mit explode()
an den Kommata als Trennzeichen trennen. Wenn das Feld leer ist, dann wird ein leeres Array gespeichert. Danach legen wir einen Counter an und starten eine Schleife, die die Beitrags-IDs durchläuft. Darin holen wir uns zuerst das Post-Objekt mit get_post()
sowie dessen Post-Format. Wenn ein Post zurückgegeben wurde und er dem richtigen Post-Format entspricht, müssen wir prüfen, ob das der erste Schleifendurchlauf ist. Wenn dem so ist, geben wir das Markup für vor dem Widget sowie den Titel aus.
Danach holen wir uns mit bornholm_get_gallery_images()
die Bilder des Beitrags und geben das erste innerhalb eines div
-Elements aus, indem wir bornholm_gallery_header()
aufrufen – danach erhöhen wir den Counter. Wenn die Schleife komplett abgearbeitet wurde und der Counter nicht mehr den Wert 0
hat, dann geben wir das Markup aus, das nach dem Widget angezeigt werden soll.
public function update( $new_instance, $old_instance ) {
$instance = $old_instance;
$instance['title'] = strip_tags( $new_instance['title'] );
$instance['gallery_ids'] = strip_tags( $new_instance['gallery_ids'] );
return $instance;
}
Code-Sprache: PHP (php)
Die update()
-Methode gleicht der aus dem anderen Widget. Bei den Galerie-IDs könnte man hier noch genauer prüfen, ob die Eingabe dem Muster aus Zahlen und Kommata entspricht, die man erwartet, aber uns reicht das in dem Fall so.
public function form( $instance ) {
$title = isset( $instance['title'] ) ? esc_attr( $instance['title'] ) : '';
$gallery_ids = isset( $instance['gallery_ids'] ) ? esc_attr( $instance['gallery_ids'] ) : '';
?>
<p><label for="<?php echo $this->get_field_id( 'title' ); ?>"><?php _e( 'Title:', 'bornholm' ); ?></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 $title; ?>"/>
</p>
<p><label
for="<?php echo $this->get_field_id( 'gallery_ids' ); ?>"><?php _e( 'Comma seperated ids of galleries you want to feature:', 'bornholm' ); ?></label>
<input class="widefat" placeholder="523, 547" id="<?php echo $this->get_field_id( 'gallery_ids' ); ?>"
name="<?php echo $this->get_field_name( 'gallery_ids' ); ?>" type="text"
value="<?php echo $gallery_ids; ?>"/></p>
<?php
}
}
Code-Sprache: JavaScript (javascript)
Auch die form()
-Methode bietet nicht wirklich Neues. Zuerst werden die beiden Werte ermittelt und gegebenenfalls auf den leeren Standard gesetzt. Im Anschluss werden wieder die beiden Felder erstellt. Natürlich muss sich ein Widget nicht auf zwei Felder beschränken – ihr könnt so viele einsetzen, wie ihr wollt.
Das wäre es auch schon – jetzt hat unser Theme zwei funktionierende Widgets, die der Nutzer in Sidebars einsetzen kann. Ich bin nicht hundertprozentig sicher, aber ich glaube, dass es im nächsten Teil um den Customizer gehen wird 🙂
Update vom 28. Dezember 2015: Ein kleiner Code-Teil wurde in diesem Teil der Reihe vergessen, weshalb die Widgets so noch nicht funktionieren – der übrige Code ist am Anfang des nächsten Teils Thema.
Der Code auf GitHub
Den Code gibt es im Repo auf GitHub. Den aktuellen Stand nach diesem Artikel zeigt Tag „v0.15“.
Die weiteren Teile meiner WordPress-Reihe:
- Das eigene WordPress-Theme erstellen – #1: Vorbesprechung und Vorbereitung
- Das eigene WordPress-Theme erstellen – #2: Die style.css und die Metadaten eures Themes
- Das eigene WordPress-Theme erstellen – #3: Die header.php und der Kopf eures Themes
- Das eigene WordPress-Theme erstellen – #4: Die index.php und die Post-Loop
- Das eigene WordPress-Theme erstellen – #5: Die content.php
- Das eigene WordPress-Theme erstellen – #6: Das Theme auf die Übersetzung vorbereiten
- Das eigene WordPress-Theme erstellen – #7: Die Sidebar und der Footer
- Das eigene WordPress-Theme erstellen – #8: Menü, Sidebars und Theme-Support in der functions.php
- Das eigene WordPress-Theme erstellen – #9: Die Einzelansicht der Beiträge und Galerien in der single.php
- Das eigene WordPress-Theme erstellen – #10: Die Galerie-Sidebar mit Galerien aus derselben Kategorie
- Das eigene WordPress-Theme erstellen – #11: Der Kommentarbereich
- Das eigene WordPress-Theme erstellen – #12: Die Galerie und ihre Ansicht in der Blog-Übersicht
- Das eigene WordPress-Theme erstellen – #13: Die Archiv-Ansichten
- Das eigene WordPress-Theme erstellen – #14: Einzelansicht einer Seite und das 404-Template
- Das eigene WordPress-Theme erstellen – #15: Die alternative Startseite
- Das eigene WordPress-Theme erstellen – #16: Die Portfolio-Ansicht
- Das eigene WordPress-Theme erstellen – #18: Der Customizer
- Das eigene WordPress-Theme erstellen – #19: Die Customizer-Einstellungen im Theme anwenden
- Das eigene WordPress-Theme erstellen – #20: Fertigstellung und Hochladen ins Directory
Dieser Beitrag ist eine Übernahme meines Beitrags für t3n.de.