Das eigene WordPress-Theme erstellen – #5: Die content.php

In dieser Serie geht es darum, ein WordPress-Theme zu erstellen – von Grund auf. Im fünften Teil beschäftigen wir uns mit der Ausgabe der Inhalte von Standard-Beiträgen in der Blogübersicht.

Wie im letzten Teil der Reihe besprochen, nutzen wir die content.php, um das Markup von Beiträgen auf der Blog-Übersicht auszugeben. Wenn keine andere content--Datei wie die content-gallery.php angelegt sind, wird für jedes Post-Format diese Datei gewählt. Für unser Theme sieht die Datei so aus:

<article id="post-<?php the_ID(); ?>" <?php post_class(); ?>> <header class="entry-header"> <?php bornholm_the_post_header( 'h1', $post ); ?> </header> <div class="entry-content"> <?php bornholm_the_content(); ?> </div> <footer class="entry-meta"> <?php bornholm_footer_meta() ?> </footer> </article>
Code-Sprache: JavaScript (javascript)

Wir umschließen einen Beitrag mit einem article-Element und weisen diesem eine ID zu. Die besteht immer aus dem Präfix post-, gefolgt von der ID des Beitrags, die wir mittels der the_ID()-Funktion ausgeben. WordPress stellt noch nützliche Klassen zur Verfügung, die mit post_class() ausgegeben werden. Beispielsweise gibt WordPress das Post-Format des Artikels aus, etwa in Form der format-gallery-Klasse. Nähere Informationen zu dieser Funktionn findet ihr auf developer.wordpress.org.

Der Header eines normalen Beitrags

Der Header eines normalen Beitrags soll die verlinkte Überschrift enthalten sowie gegebenenfalls das Featured Image. Da wir diese Funktionalität häufiger brauchen, ist sie in die Funktion bornholm_the_post_header() ausgelagert. Als Parameter muss die Hierarchie der Überschrift und das $post-Objekt übergeben werden. Diese Funktion schreiben wir in die functions.php, die ebenfalls in die oberste Ebene des Theme-Ordners gehört:

<?php /** * Displays the header for normal posts * * @param $heading * * @return string Formatted output in HTML */ function bornholm_the_post_header( $heading, $post ) { if ( has_post_thumbnail() ) { if ( ! is_single() ) { ?> <a href="<?php esc_url( the_permalink() ); ?>"> <?php } ?> echo '<' . $heading . ' class="entry-title">'; the_title(); echo '</' . $heading . '>'; ?> <figure class="featured-image"> <?php the_post_thumbnail(); ?> </figure> <?php if ( ! is_single() ) { ?> </a> <?php } } else { bornholm_post_title( $heading, $post ); } }
Code-Sprache: HTML, XML (xml)

Zuerst wird mit der has_post_thumbnail()-Funktion geprüft, ob der Beitrag ein Featured Image hat. Da wir den Link auf die Detailseite nur setzen wollen, wenn wir uns nicht auf derselben befinden, und diese Funktion auch für die Einzelansicht benutzt wird, prüfen wir mit ! is_single(), ob die angezeigte Seite keine Einzelseite ist. Befinden wir uns nicht auf einer Einzelseite, geben wir mit Hilfe der the_permalink()-Funktion einen Link auf die Einzelseite des Beitrags aus.

Anschließend möchten wir den Titel des Beitrags anzeigen. Wir setzen uns also das Überschriften-Element mit der übergebenen Hierarchie zusammen und geben darin den Titel mit der the_title()-Funktion aus. Für die Ausgabe des Featured Image in dem figure-Element nutzen wir die Funktion the_post_thumbnail(). Falls es sich nicht um eine Einzelansicht handelt, schließen wir das Link-Element wieder. Hat der Beitrag kein Featured Image, so rufen wir die bornholm_post_title()-Funktion auf und übergeben die zwei bereits bekannten Parameter. Auch diese Funktion kommt in die functions.php:

/** * Displays the post title * * @param $heading * * @return string Formatted output in HTML */ function bornholm_post_title( $heading, $post ) { echo '<' . $heading . ' class="entry-title">'; if ( ! is_single() ) { ?> <a href="<?php esc_url( the_permalink() ); ?>"> <?php } the_title(); if ( ! is_single() ) { ?> </a> <?php } echo '</' . $heading . '>'; }
Code-Sprache: PHP (php)

Das sollte durch die Besprechung der vorherigen Funktion eigentlich selbsterklärend sein. Wir geben wieder das Überschriften-Element aus sowie gegebenenfalls den Link zu der Einzelseite. Darin kommt mit the_title() die Überschrift des Beitrags.

Der Inhalt des Beitrags mit angepasstem Weiterlesen-Link

Kommen wir zurück zur content.php. Um den Inhalt des Beitrags auf der Blog-Übersicht kümmert sich dieser Abschnitt:

<div class="entry-content"> <?php bornholm_the_content(); ?> </div>
Code-Sprache: HTML, XML (xml)

Und die bornholm_the_content()-Funktion – wieder anzusiedeln in der functions.php – sieht so aus:

/** * Displays the content with customized more link * * @return string Formatted output in HTML */ function bornholm_the_content() { $text = _x( 'Continue reading “%s”', 's = post title', 'bornholm' ); $more = sprintf( $text, esc_html( get_the_title() ) ); the_content( $more ); }
Code-Sprache: PHP (php)

In WordPress kann ja bekanntlich ein Weiterlesen-Tag eingefügt werden. Der Standardtext, der dafür ausgegeben wird, ist „Read more…“ oder in der deutschen Übersetzung „Weiterlesen …“. Wir möchten aber gerne den Titel des Beitrags mit in diesen Weiterlesen-Link integrieren. Im Englischen soll das dann, wenn der Beitrag beispielsweise „WordPress-News“ heißt, so aussehen: Continue reading “WordPress-News”. Natürlich übersetzbar. Die Übersetzbarkeit ermöglicht die die erste Zeile der Funktion. Um den Artikel hier nicht zu lang werden zu lassen, wird sich der nächste Beitrag damit beschäftigen, wie ein WordPress-Theme für die Übersetzung vorbereitet werden kann.

Mit der sprintf()-Funktion wird in der nächsten Zeile in den Weiterlesen-Text der Titel eingefügt, der von der get_the_title()-Funktion bereitgestellt wird. Zuletzt übergeben wir den modifizierten Text an die WordPress-eigene the_content()-Funktion, die den Inhalt des Beitrags ausgibt.

Die Meta-Informationen im Footer

Zum Schluss braucht ein Beitrag noch einen Footer. In der content.php ist dafür dieser Teil zuständig:

<footer class="entry-meta"> <?php bornholm_footer_meta() ?> </footer>
Code-Sprache: HTML, XML (xml)

Die Funktion bornholm_footer_meta() kommt wieder in die functions.php:

/** * Displays the footer for a post * * @return string Formatted output in HTML */ function bornholm_footer_meta() { ?> <p> <a href="<?php esc_url( the_permalink() ); ?>"><?php echo sprintf( _x( '%1$s @ %2$s', '1 = date, 2 = time', 'bornholm' ), get_the_date(), get_the_time() );?></a> <?php $show_sep = true; bornholm_show_seperator( $show_sep ); $show_sep = false; $category_list = get_the_category_list( _x( ', ', 'term delimiter', 'bornholm' ) ); if ( $category_list ) { bornholm_category_list( $category_list ); $show_sep = true; } $tag_list = get_the_tag_list( '', _x( ', ', 'term delimiter', 'bornholm' ) ); if ( $tag_list ) { bornholm_show_seperator( $show_sep ); bornholm_tag_list( $tag_list ); $show_sep = true; } bornholm_show_seperator( $show_sep ); ?> <span class="author"> <?php _e( 'Author:', 'bornholm' );?> <?php the_author(); ?> </span> <?php $show_sep = true; if ( get_bornholm_comment_count() != 0 ) { bornholm_show_seperator( $show_sep ); ?> <a href="<?php echo esc_url( get_the_permalink() ) . "#comments-title"; ?>"> <?php echo get_bornholm_comment_count(); ?> </a> <?php $show_sep = true; } if ( get_bornholm_trackback_count() != 0 ) { bornholm_show_seperator( $show_sep ); ?> <a href="<?php echo esc_url( get_the_permalink() ) . "#trackbacks-title"; ?>"> <?php echo get_bornholm_trackback_count(); ?> </a> <?php } edit_post_link( __( 'Edit', 'bornholm' ), '<span class="edit-link"> · ', '</span>' ); ?> </p> <?php }
Code-Sprache: JavaScript (javascript)

An erster Stelle im Footer steht das Datum und die Uhrzeit der Veröffentlichung, die wie der Titel auch auf die Einzelseite verlinken. Das Datum bekommen wir mit der get_the_date()-, die Uhrzeit mit der get_the_time()-Funktion. Das Datum und die Zeit wird dabei in dem Format angezeigt, das der Nutzer im Backend eingestellt hat. Die Anordnung kann von einem Übersetzer angepasst werden, doch dazu wie gesagt im nächsten Beitrag mehr.

Da es sein kann, dass kein Tag oder keine Kategorie angegeben werden, müssen wir das immer überprüfen, bevor wir das Trennzeichen zwischen den einzelnen Elementen des Footers ausgeben. Wir setzen also die Variable $show_sep auf true und rufen die bornholm_show_seperator()-Funktion auf. Diese Funktion sieht so aus:

/** * Displays the seperator (for example between tag list and category list * * @param $show_sep * * @return string Formatted output in HTML */ function bornholm_show_seperator( $show_sep ) { if ( $show_sep ) { ?> <span class="sep"> · </span> <?php } }
Code-Sprache: JavaScript (javascript)

Es wird geprüft, ob $show_sep wahr ist und dann der Seperator ausgegeben. Da der Seperator nun ausgegeben wurde, setzen wir in der bornholm_footer_meta()-Funktion die $show_sep-Variable auf false. Als nächstes wollen wir die Liste der Kategorien ausgeben. Die holen wir uns über die get_the_category_list()-Funktion, mit einem Komma als Trennzeichen. Wenn dieser Funktionsaufruf ein Ergebnis zurückgibt, also Kategorien festgelegt wurden, übergeben wir das Ergebnis an die bornholm_category_list()-Funktion, die so aussieht:

/** * Displays the category list * * @param $category_list * * @return string Formatted output in HTML */ function bornholm_category_list( $category_list ) { ?> <span class="cat-links"> <?php _e( 'Posted in ', 'bornholm' ); echo $category_list; ?> </span> <?php }
Code-Sprache: JavaScript (javascript)

Hier geben wir innerhalb eines span-Elements die Liste der Kategorien aus, mit einem übersetzungsfähigen „Posted in “ vorangestellt. Wieder zurück in der bornholm_footer_meta()-Funktion setzen wir $show_sep auf true und verfahren in ähnlicher Weise mit der Liste der Tags. Die bornholm_tag_list()-Funktion sieht so aus:

/** * Displays the tag list * * @param $tag_list * * @return string Formatted output in HTML */ function bornholm_tag_list( $tag_list ) { ?> <span class="tag-links"> <?php _e( 'Tagged ', 'bornholm' ); echo $tag_list; ?> </span> <?php }
Code-Sprache: JavaScript (javascript)

Als nächstes geben wir in der Funktion für die Footer-Metadaten den Autoren aus. Dafür zuständig ist die Funktion the_author(). Nun möchten wir noch getrennt voneinander die Anzahl der Kommentare und Trackbacks darstellen. WordPress kann standardmäßig nur eine Gesamtzahl der Reaktionen ausgeben. weshalb wir uns hier zwei kleine Funktionen bauen müssen, die sich recht ähnlich sind. Hier sind sie:

/** * Returns the number of comments for a post * * @return string */ function get_bornholm_comment_count() { global $post; $the_post_id = $post->ID; global $wpdb; $co_number = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM $wpdb->comments WHERE comment_type = %s AND comment_post_ID = %d AND comment_approved = %d", ' ', $the_post_id, 1 ) ); if ( $co_number == 0 ) { return $co_number; } elseif ( $co_number == 1 ) { $co_number = $co_number . __( ' Comment', 'bornholm' );   return $co_number; } else { $co_number = $co_number . __( ' Comments', 'bornholm' );   return $co_number; } }     /** * Returns the Number of trackbacks for a post * * @return string */ function get_bornholm_trackback_count() { global $post; $the_post_id = $post->ID; global $wpdb; $tb_number = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM $wpdb->comments WHERE comment_type != %s AND comment_post_ID = %d AND comment_approved = %d", ' ', $the_post_id, 1 ) ); if ( $tb_number == 0 ) { return $tb_number; } elseif ( $tb_number == 1 ) { $tb_number = $tb_number . __( ' Trackback', 'bornholm' );   return $tb_number; } else { $tb_number = $tb_number . __( ' Trackbacks', 'bornholm' );   return $tb_number; } }
Code-Sprache: PHP (php)

Ich erkläre euch den Code anhand der ersten Funktion, die die Anzahl der Kommentare ausgibt. Zuerst sorgen wir dafür, dass wir auf das $post-Objekt zugreifen können und speichern anschließend die ID des aktuellen Beitrags in der $the_post_id-Variable. Für Datenbankabfragen gibt es in WordPress die $wpdb-Klasse. Da wir nur einen Wert aus der Datenbank holen möchten, nutzen wir die get_var()-Methode. Um die SQL-Abfrage für eine sichere Ausführung vorzubereiten, kommt die prepare()-Methode zum Einsatz.

Es folgt als erster Parameter die SQL-Abfrage. Mit $wpdb-> können wir dabei dynamisch auf das Tabellenpräfix zugreifen. Die anderen Parameter sind die Werte für die jeweiligen Platzhalter in der WHERE-Klausel. Eine detaillierte Erklärung der Klasse und ihrer Methoden findet ihr wieder auf developer.wordpress.org. Danach prüfen wir, ob keine Kommentare gefunden wurden und geben die Zahl 0 zurück. Wenn ein Kommentar gefunden wurde, geben wir 1 Comment zurück und in allen anderen Fällen die Anzahl gefolgt von Comments. Sehr ähnlich ist die Funktion für die Trackbacks aufgebaut.

Zurück zu dem Abschnitt in der Footer-Meta-Funktion:

if ( get_bornholm_comment_count() != 0 ) { bornholm_show_seperator( $show_sep ); ?> <a href="<?php echo esc_url( get_the_permalink() ) . "#comments-title"; ?>"> <?php echo get_bornholm_comment_count(); ?> </a> <?php $show_sep = true; } if ( get_bornholm_trackback_count() != 0 ) { bornholm_show_seperator( $show_sep ); ?> <a href="<?php echo esc_url( get_the_permalink() ) . "#trackbacks-title"; ?>"> <?php echo get_bornholm_trackback_count(); ?> </a> <?php }
Code-Sprache: HTML, XML (xml)

Wir prüfen für beide Fälle, ob das Ergebnis ungleich Null ist. Ist das so, geben wir gegebenenfalls den Seperator aus und als Link auf den Titel des Kommentar- beziehungsweise Trackback-Bereichs die Anzahl der Kommentare oder Trackbacks. Zum Schluss geben wir mit der edit_post_link()-Funktion für Nutzer mit den erforderlichen Rechten einen Link auf die Bearbeitungsseite im Backend aus.

Wenn ihr euch nun eure Installation mal anschaut, dann solltet ihr bereits Inhalte auf eurer Seite sehen. Als nächstes müssen wir uns jetzt um die Sidebar und den Footer kümmern, die wir in der index.php im letzten Teil ja eingebunden aber noch nicht angelegt haben. Hier greift WordPress noch auf einen Fallback zurück. Aber wie gesagt wird sich der nächste Teil erst mal als kleiner Exkurs um die Vorbereitung für die Übersetzung kümmern.

Der Code auf GitHub

Wie immer findet ihr den Code im GitHub-Repository zur Artikelreihe. Den Code-Stand nach diesem Teil findet ihr in Tag „v0.4“.

Die weiteren Teile meiner WordPress-Reihe:

Dieser Beitrag ist eine Übernahme meines Beitrags für t3n.de.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert