Du hast deinen AdBlocker an?

Es wäre ein Traum, wenn du ihn für t3n.de deaktivierst. Wir zeigen dir gerne, wie das geht. Und natürlich erklären wir dir auch, warum uns das so wichtig ist. Digitales High-five, deine t3n-Redaktion

Entwicklung & Design

Das eigene WordPress-Theme erstellen – #9: Die Einzelansicht der Beiträge und Galerien in der single.php

In dieser Serie geht es darum, ein WordPress-Theme zu erstellen – von Grund auf. Der neunte Teil beschäftigt sich mit der single.php, die für die Anzeige eines einzelnen Beitrags zuständig ist.

Bisher können wir die Anzeige eines einzelnen Beitrags noch nicht von der Übersichtsseite unterscheiden. Dafür gibt es die single.php-Datei. Diese Template-Datei wird von WordPress aufgerufen, wenn ein einzelner Beitrag angezeigt wird. Hier nehmen wir auch gleich die Anpassungen für die Galerie-Ansicht vor, die ein großes Featured Image im Header des Beitrags anzeigen soll. Wie das aussieht, seht ihr im folgenden Screenshot. Oben ist die Einzelansicht einer Galerie abgebildet, unten die Einzelansicht eines ganz normalen Beitrags.

Die zwei verschiedenen Anzeigemöglichkeiten in der single.php des WordPress-Themes: Oben eine Galerie, unten ein normaler Artikel. (Screenshot: eigene WordPress-Installation; Fotos: Dennis Brinkmann)
Die zwei verschiedenen Anzeigemöglichkeiten in der single.php des WordPress-Themes: Oben eine Galerie, unten ein normaler Artikel. (Screenshot: eigene WordPress-Installation; Fotos: Dennis Brinkmann)

Da die single.php durch die Einrückungen hier im Gesamten nur schwer lesbar wäre, poste ich sie gleich stückweise. Den ersten Teil kennen wir schon aus dem Artikel mit der index.php. Wir binden die header.php ein und starten den Loop.

<?php get_header(); ?>
    <main role="main">
        <?php
        while ( have_posts() ) {
            the_post();

Nun müssen wir für die veränderte Anzeige im Header des Beitrags rausfinden, ob es sich um ein Galerie-Post-Format handelt. Dafür gibt es die get_post_format()-Funktion, der die ID des Beitrags übergeben werden muss. Die ID ist im $post-Objekt gespeichert. Wir sichern also zuerst das Ergebnis dieser Abfrage in einer Variable und führen dann im header-Element die Fallunterscheidung durch:

$format = get_post_format( $post->ID ); ?>
<article id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
    <header class="entry-header clearfix">
        <?php if ( $format == 'gallery' ) {
            $images = bornholm_get_gallery_images( $post->ID );
            bornholm_gallery_header( 'h1', $images, 'bornholm_large_gallery_image_for_single_view', $post );
        } else {
            bornholm_the_post_header( 'h1', $post );
        } ?>
    </header>

Die Funktion von the_ID() und post_class() haben wir schon im Beitrag zur content.php besprochen. Innerhalb des header-Elements prüfen wir, ob das Ergebnis des get_post_format()-Aufrufs dem Wert gallery entspricht. Wenn das der Fall ist, müssen wir uns die Bilder aus der Galerie besorgen und das erste davon im Header anzeigen. Andernfalls geben wir den normalen Header mit der bornholm_the_post_header()-Funktion aus, die ebenfalls schon in dem Teil mit der content.php erläutert wurde.

Beschäftigen wir uns also näher mit dem Fall, dass eine Galerie angezeigt wird. Wir wollen die Galeriebilder in der $images-Variable speichern und rufen dafür die bornholm_get_gallery_images()-Funktion auf, der wir die ID des Beitrags übergeben. An dieser Stelle vielen Dank an Thomas Scholz, der mir den Großteil dieser Funktion geschrieben und mir bei der Überarbeitung des Theme-Codes einige hilfreiche Tipps gegeben hat. Diese Funktion kommt in die functions.php und sieht wie folgt aus:

/**
 * Fetch image post objects for all gallery images in a post.
 *
 * @param $post_id
 *
 *@return array
 */
function bornholm_get_gallery_images( $post_id ) {
 
    $post = get_post( $post_id );
 
    // Den Beitrag gibt es nicht, oder er ist leer.
    if ( ! $post || empty ( $post->post_content ) ) {
        return array();
    }
 
    $galleries = get_post_galleries( $post, false );
    if ( empty ( $galleries ) ) {
        return array();
    }
    $ids = array();
    foreach ( $galleries as $gallery ) {
        if ( ! empty ( $gallery['ids'] ) ) {
            $ids = array_merge( $ids, explode( ',', $gallery['ids'] ) );
        }
    }
    $ids = array_unique( $ids );
    if ( empty ( $ids ) ) {
        $attachments = get_children( array(
            'post_parent'    => $post_id,
            'post_status'    => 'inherit',
            'post_type'      => 'attachment',
            'post_mime_type' => 'image',
            'order'          => 'ASC',
            'orderby'        => 'menu_order',
        ) );
        if ( empty ( $attachments ) ) {
            return array();
        }
    }
 
    $images = get_posts(
        array(
            'post_type'      => 'attachment',
            'post_mime_type' => 'image',
            'orderby'        => 'post__in',
            'numberposts'    => 999,
            'include'        => $ids
        )
    );
    if ( ! $images && ! $attachments ) {
        return array();
    } elseif ( ! $images ) {
	    $images = $attachments;
    }
 
    return $images;
}

Zuerst holen wir uns mit der get_post()-Funktion das $post-Objekt. Dadurch können wir nun prüfen, ob es den Beitrag überhaupt gibt oder ob er leer ist. In beiden Fällen beenden wir den Durchlauf der Funktion und geben ein leeres Array zurück. Anschließend wollen wir die Galerien des Beitrags ermitteln. Dafür bietet WordPress uns die get_post_galleries()-Funktion, die als ersten Parameter das Post-Objekt erwartet. Der zweite Parameter muss ein boolescher Wert sein und gibt an, ob die Rückgabe als HTML oder als Array erfolgen soll. Da wir für die weitere Verarbeitung ein Array benötigen, übergeben wir hier false.

Im nächsten Schritt prüfen wir, ob es Galerien in dem Beitrag gibt und geben andernfalls wieder ein leeres Array zurück. Jetzt brauchen wir die IDs von den Bildern in einem Array. Das Ergebnis-Array aus dem get_post_galleries()-Aufruf sieht aber bei zwei Galerien in einem Beitrag beispielhaft so aus:

Array ( 
    [0] => Array ( 
        [ids] => 769,768 
        [src] => Array ( 
            [0] => http://example.com/2015/10/20/img.jpg 
            [1] => http://example.com/2015/10/20/img-1.jpg 
        ) 
    )
    [1] => Array ( 
        [ids] => 456,345
        [src] => Array ( 
            [0] => http://example.com/2015/10/20/img-2.jpg 
            [1] => http://example.com/2015/10/20/img-3.jpg 
        ) 
    ) 
)

Wir müssen also die IDs aus dem ids-Eintrag des Arrays bekommen. Da ja mehrere Galerien in einem Beitrag verwendet werden können, müssen wir die einzelnen Ergebnisse zu einem langen ID-Array zusammensetzen. Das ist Aufgabe dieses Code-Teils:

$ids = array();
foreach ( $galleries as $gallery ) {
    if ( ! empty ( $gallery['ids'] ) ) {
        $ids = array_merge( $ids, explode( ',', $gallery['ids'] ) );
    }
}
$ids = array_unique( $ids );

Wir erstellen zuerst ein leeres Array und speichern es in der $ids-Variable. Anschließend durchlaufen wir in einer foreach-Schleife alle Galerien aus dem Beitrag und prüfen darin, ob wir überhaupt IDs in dem Array haben. Ist das der Fall, müssen wir gedanklich die nächste Zeile von innen nach außen durchgehen. Damit haben wir zunächst diesen Teil:

explode( ',', $gallery['ids'] )

Dadurch werden die Werte vom Array-Schlüssel $ids an dem übergebenen Trennzeichen , getrennt und als Array zurückgegeben. Das sieht für die erste Galerie aus unserem Beispiel so aus:

Array ( 
    [0] => 769
    [1] => 768
)

Dieses Array hängen wir mit der array_merge()-Funktion an das $ids-Array an. Hier wird also das lange Array von IDs gebildet. Sind alle Galerien abgearbeitet, werden mit der array_unique()-Funktion doppelte Werte aus dem Array entfernt.

Nun gibt es zwei Varianten, wie der gallery-Shortcode in WordPress eingesetzt werden kann. Einmal mit übergebenen IDs der Bilder und einmal ohne. Wenn keine IDs angegeben werden, zeigt der Shortcode einfach alle Bilder an, die zu dem Beitrag hochgeladen wurden. In diesem Fall haben wir zwar keine IDs aus dem foreach-Durchlauf, wir wollen aber natürlich trotzdem ein Bild als Titelbild anzeigen.

Wenn also die $ids-Variable an dieser Stelle der Funktion leer ist, wurde ein gallery-Shortcode ohne IDs eingesetzt. In diesem Fall kommt folgender Code zum Einsatz:

if ( empty ( $ids ) ) {
    $attachments = get_children( array(
        'post_parent'    => $post_id,
        'post_status'    => 'inherit',
        'post_type'      => 'attachment',
        'post_mime_type' => 'image',
        'order'          => 'ASC',
        'orderby'        => 'menu_order',
    ) );
    if ( empty ( $attachments ) ) {
        return array();
    }
}

Mit der get_children()-Funktion können wir die Anhänge eines Beitrag ermitteln – also alle Medien, die in einem Beitrag über die Schaltfläche „Dateien hinzufügen“ hochgeladen wurden. Um die Dateien für den richtigen Beitrag zu bekommen, übergeben wir in dem Parameter-Array für den Schlüssel post_parent die ID des Beitrags. Als post_status geben wir inherit an, was dann dem Post-Status des Beitrags entspricht. Der Post-Type soll einem Anhang entsprechen und der Typ des Anhangs soll image sein. Das Ganze soll aufsteigend nach der Menü-Reihenfolge sortiert werden – das entspricht in diesem Fall der Reihenfolge des Hochladens.

Wenn das Ergebnis des Aufrufs leer ist, geben wir erneut ein leeres Array zurück. Für den Normalfall, dass ein gallery-Shortcode mit IDs der Bilder eingesetzt wird, nutzen wir den folgenden Code-Schnipsel, um die Post-Objekte der Bilder zu erhalten:

$images = get_posts(
    array(
        'post_type'      => 'attachment',
        'post_mime_type' => 'image',
        'orderby'        => 'post__in',
        'numberposts'    => 999,
        'include'        => $ids
    )
);

Wir rufen die get_posts()-Funktion auf und möchten nur Objekte, die von Typ attachment und gleichzeitig ein Bild sind. Darüber hinaus sollen sie so sortiert werden, wie sie in dem Array $ids vorkommen, das wir dem include-Schlüssel übergeben. Kurz gesagt bekommen wir hier als Ergebnis ein Array mit den Post-Objekten der Bilder, die zu den ermittelten IDs aus den gallery-Shortcodes gehören.

Abschließend prüfen wir, ob beide Aufrufe kein Ergebnis geliefert haben und geben in dem Fall ein leeres Array zurück. Wenn hingegen nur der Aufruf der get_posts()-Funktion leer ist, weisen wir der $images-Variable das Ergebnis des get_children()-Aufrufs zu. Andernfalls behält die $images-Variable den Wert des get_posts()-Aufrufs. Danach geben wir das Ergebnis zurück:

if ( ! $images && ! $attachments ) {
    return array();
} elseif ( ! $images ) {
    $images = $attachments;
}
 
return $images;

Finde einen Job, den du liebst

Bitte beachte unsere Community-Richtlinien

Schreib den ersten Kommentar!

Melde dich mit deinem t3n-Account an oder fülle die unteren Felder aus.

Abbrechen