Das eigene WordPress-Theme erstellen – #11: Der Kommentarbereich

In dieser Artikelreihe geht es darum, ein WordPress-Theme zu erstellen – von Grund auf. Im elften Teil werden wir uns um den Kommentarbereich kümmern.

In den letzten zwei Teilen der Reihe haben wir die single.php erstellt und die Sidebar für Galerien in der Einzelansicht. Um die Einzelansicht zu vervollständigen, fehlt uns noch der Kommentarbereich, der in der single.php mit folgender Zeile eingebunden wurde:

comments_template( '', true );
Code-Sprache: JavaScript (javascript)

Diese Zeile bindet entweder die comments.php des Themes ein oder, wenn nicht vorhanden, das Kommentar-Template des Standard-Themes. In unserem Kommentarbereich sollen zuerst die Kommentare und anschließend die Pingbacks angezeigt werden – gefolgt vom Kommentarformular.

Die comments.php unseres Themes sieht folgendermaßen aus:

<?php if ( post_password_required() ) { return; } ?> <div id="comments" class="comments-area"> <?php if ( have_comments() ) { if ( ! empty( $comments_by_type['comment'] ) ) { ?> <h2 id="comments-title"> <?php echo get_bornholm_comment_count(); ?> </h2>   <ol class="commentlist"> <?php wp_list_comments( array( 'callback' => 'bornholm_comment', 'style' => 'ol', 'type' => 'comment' ) ); ?> </ol> <?php } if ( ! empty( $comments_by_type['pings'] ) ) { ?> <h2 id="trackbacks-title"> <?php echo get_bornholm_trackback_count(); ?> </h2>   <ol class="commentlist"> <?php wp_list_comments( array( 'callback' => 'bornholm_comment', 'type' => 'pings' ) ); ?> </ol> <?php } if ( get_comment_pages_count() > 1 && get_option( 'page_comments' ) ) { ?> <nav id="comment-nav-below" class="navigation" role="navigation"> <h2 class="screen-reader-text"><?php _e( 'Comment navigation', 'bornholm' ); ?></h2>   <div class="nav-previous"> <?php previous_comments_link( __( '← Older Comments', 'bornholm' ) ); ?> </div> <div class="nav-next"> <?php next_comments_link( __( 'Newer Comments →', 'bornholm' ) ); ?> </div> </nav> <?php } if ( ! comments_open() && get_comments_number() ) { ?> <p class="nocomments"><?php _e( 'Comments are closed.', 'bornholm' ); ?></p> <?php }   } comment_form( array( 'comment_notes_after' => '', 'label_submit' => __( 'Submit Comment', 'bornholm' ) ) ); ?> </div>
Code-Sprache: HTML, XML (xml)

Zuerst prüfen wir mit post_password_required(), ob ein passwortgeschützter Beitrag angezeigt wird und das korrekte Passwort nicht eingegeben wurde. Wenn das icht der Fall ist, starten wir die Ausgabe des Kommentarbereichs. Innerhalb des div wird geprüft, ob zu dem Beitrag Kommentare vorhanden sind. Von der have_comments()-Funktion werden sowohl Kommentare als auch Pingbacks berücksichtigt. Als nächstes prüfen wir, ob Kommentare vorhanden sind – hier aber wirklich nur auf Kommentare, nicht auf Pingbacks:

if ( ! empty( $comments_by_type['comment'] ) ) {
Code-Sprache: PHP (php)

Dieses Array $comments_by_tpye können wir deshalb nutzen, weil wir beim Aufruf der comments_template()-Funktion als zweiten Parameter true übergeben haben. Durch diese Angabe wird der folgende Code innerhalb der comments_template()-Funktion ausgeführt und stellt uns die Kommentare getrennt nach Typ zur Verfügung:

if ( $separate_comments ) { $wp_query->comments_by_type = separate_comments($comments); $comments_by_type = &$wp_query->comments_by_type; }
Code-Sprache: PHP (php)

Zurück in die comments.php. Wenn wir Kommentare gefunden haben, geben wir mit der schon bekannten get_bornholm_comment_count()-Funktion die Anzahl aus. Anschließend folgt die Liste der Kommentare, die wir über wp_list_comments() ausgeben können. Wichtig ist hier vor allem die Angabe comment für den type. Um die Ausgabe der Kommentare verändern zu können, geben wir für callback als Wert bornholm_comment an, was der bornholm_comment()-Funktion entspricht, die in die functions.php gehört:

/** * Template for comments and pingbacks. * * To override this walker in a child theme without modifying the comments template * simply create your own bornholm_comment(), and that function will be used instead. * * Used as a callback by wp_list_comments() for displaying the comments. */ function bornholm_comment( $comment, $args, $depth ) { $GLOBALS['comment'] = $comment; switch ( $comment->comment_type ) : case 'pingback' : case 'trackback' : ?> <li <?php comment_class(); ?> id="comment-<?php comment_ID(); ?>"> <p> <?php _e( 'Trackback:', 'bornholm' ); ?> <?php esc_url( comment_author_link() ); ?> <?php esc_url( edit_comment_link( __( '(Edit)', 'bornholm' ), '<span class="edit-link">', '</span>' ) ); ?> </p> <?php break; default : global $post; ?> <li <?php comment_class(); ?> id="li-comment-<?php comment_ID(); ?>"> <article id="comment-<?php comment_ID(); ?>" class="comment"> <header class="comment-meta comment-author vcard clearfix"> <?php echo get_avatar( $comment, 100 ); ?> <cite class="fn"> <?php esc_url( comment_author_link() ); ?> </cite>   <?php printf( '<a href="%1$s"><time datetime="%2$s">%3$s</time></a>', esc_url( get_comment_link( $comment->comment_ID ) ), get_comment_time( 'c' ), sprintf( _x( '%1$s @ %2$s', '1=date 2=time', 'bornholm' ), get_comment_date(), get_comment_time() ) ); ?> </header>   <?php if ( '0' == $comment->comment_approved ) { ?> <p class="comment-awaiting-moderation"> <?php _e( 'Your comment is awaiting moderation.', 'bornholm' ); ?> </p> <?php } ?>   <section class="comment-content comment"> <?php comment_text(); ?> <?php esc_url( edit_comment_link( __( 'Edit', 'bornholm' ), '<p class="edit-link">', '</p>' ) ); ?> </section>   <div class="reply"> <?php esc_url( comment_reply_link( array( 'reply_text' => __( 'Reply', 'bornholm' ), 'depth' => $depth, 'max_depth' => $args['max_depth'] ) ) ); ?> </div> </article> <?php break; endswitch; // end comment_type check }
Code-Sprache: JavaScript (javascript)

Diese Funktion kümmert sich sowohl um die Anzeige der Kommentare als auch um die Pingbacks. Diese Fallunterscheidung tätigen wir in einer switch-Anweisung, in der wir den Kommentar-Typ überprüfen. Wenn es sich um einen Ping- oder Trackback handelt, geben wir ein Listenelement aus und darin den Trackback. Mit comment_author_link() wird dabei der Titel der Website als Link ausgegeben. Über die edit_comment_link()-Funktion fügen wir hinter den Trackback einen Link zum Bearbeiten ein, der nur für berechtigte Nutzer sichtbar ist. Das schließende li-Tag setzt WordPress selbst!

Wenn es sich nicht um einen Ping- oder Trackback handelt, geben wir einen Kommentar aus. Auch hier beginnen wir wieder mit einem öffnenden li-Tag und reichern das Element durch comment_class() mit hilfreichen Klassen an – ähnlich wie bei body_class(). Innerhalb des header-Elements soll der Gravatar des Nutzers mit einer Breite von 100 Pixeln angezeigt werden. Dafür sorgt die get_avatar()-Funktion, die als ersten Parameter das Kommentar-Objekt übergeben bekommt und als zweiten die Größe des Bildes. Den Namen des Kommentierenden geben wir wieder mit der comment_author_link()-Funktion aus.

Es folgt das Datum und die Zeit des Kommentars:

<?php printf( '<a href="%1$s"><time datetime="%2$s">%3$s</time></a>', esc_url( get_comment_link( $comment->comment_ID ) ), get_comment_time( 'c' ), sprintf( _x( '%1$s @ %2$s', '1=date 2=time', 'bornholm' ), get_comment_date(), get_comment_time() ) ); ?>
Code-Sprache: HTML, XML (xml)

Als ersten Parameter übergeben wir an die printf()-Funktion das HTML-Markup mit den entsprechenden Platzhaltern. Der zweite Parameter ist der Permalink des Kommentars, der mit der get_comment_link()-Funktion ermittelt wird. Als nächstes ermitteln wir für das datetime-Attribut den Zeitpunkt, an dem der Kommentar geschrieben wurde. get_comment_time() gibt mit dem Parameter c einen String dieses Formats zurück: 2015-06-11T12:48:09+00:00.

Zuletzt bauen wir den Zeit-String zusammen, der angezeigt werden soll. Wir holen uns das Datum und die Zeit über die entsprechenden Funktionen und übergeben diesmal keinen Parameter. So wird das Format gewählt, das der Nutzer im Backend eingestellt hat. Damit wäre der header eines Kommentars fertig. Als nächstes geben wir einen Hinweis für den Autor eines Kommentars aus, wenn der Kommentar noch freigeschaltet werden muss:

<?php if ( '0' == $comment->comment_approved ) { ?> <p class="comment-awaiting-moderation"> <?php _e( 'Your comment is awaiting moderation.', 'bornholm' ); ?> </p> <?php } ?>
Code-Sprache: HTML, XML (xml)

Wir prüfen zuerst, ob der Wert comment_approved des Kommentar-Objekts 0 ist. In dem Fall geben wir eine kurze Nachricht aus, dass der Kommentar noch nicht freigeschaltet ist. Danach kommt der eigentliche Kommentar an die Reihe.

<section class="comment-content comment"> <?php comment_text(); ?> <?php esc_url( edit_comment_link( __( 'Edit', 'bornholm' ), '<p class="edit-link">', '</p>' ) ); ?> </section>   <div class="reply"> <?php esc_url( comment_reply_link( array( 'reply_text' => __( 'Reply', 'bornholm' ), 'depth' => $depth, 'max_depth' => $args['max_depth'] ) ) ); ?> </div>
Code-Sprache: HTML, XML (xml)

Innerhalb des section-Elements wird mit der comment_text()-Funktion der Inhalt des Kommentars ausgegeben. Darüber hinaus wird wieder ein Link zur Bearbeitungsseite integriert. In einem eigenen div geben wir im Anschluss einen Link zum direkten Beantworten des Kommentars aus. Dafür übergeben wir an comment_reply_link() die Parameter, die wir verändern wollen. Als Text für den Link geben wir Reply an und die Verschachtelungstiefe soll so übernommen werden, wie der Nutzer es im Backend eingestellt hat.

Nachdem wir uns durch diese Funktion gewühlt haben, kommen wir zurück zur comments.php. Die Ausgabe der Pingbacks läuft dabei nach demselben Schema ab, wie die Ausgabe der Kommentare. Wir geben wieder als Callback-Funktion bornholm_comment an. Im Anschluss müssen wir eventuell eine Kommentar-Navigation ausgeben:

if ( get_comment_pages_count() > 1 && get_option( 'page_comments' ) ) { ?> <nav id="comment-nav-below" class="navigation" role="navigation"> <h2 class="screen-reader-text"><?php _e( 'Comment navigation', 'bornholm' ); ?></h2>   <div class="nav-previous"> <?php previous_comments_link( __( '← Older Comments', 'bornholm' ) ); ?> </div> <div class="nav-next"> <?php next_comments_link( __( 'Newer Comments →', 'bornholm' ) ); ?> </div> </nav> <?php }
Code-Sprache: HTML, XML (xml)

Wir prüfen zuerst, ob mehr als eine Kommentarseite vorhanden ist und ob Kommentare überhaupt nach einer bestimmten Anzahl auf eine neue Seite umgebrochen werden sollen. Ist das der Fall, geben wir innerhalb eines nav-Elements zuerst eine Überschrift für Screen-Reader-Nutzer aus. Im Anschluss werden mit previous_comments_link() und next_comments_link() die entsprechenden Links ausgegeben. Ab WordPress 4.4 wird es dafür die the_comments_navigation()-Funktion geben, die diesen Schritt vereinfacht.

        if ( ! comments_open() && get_comments_number() ) { ?> <p class="nocomments"><?php _e( 'Comments are closed.', 'bornholm' ); ?></p> <?php }   } comment_form( array( 'comment_notes_after' => '', 'label_submit' => __( 'Submit Comment', 'bornholm' ) ) ); ?> </div>
Code-Sprache: HTML, XML (xml)

Zum Abschluss geben wir einen Hinweis auf die deaktivierte Kommentarfunktion aus, wenn Kommentare deaktiviert aber davor schon Kommentare geschrieben wurden. Zuletzt folgt das Kommentarformluar, das über die comment_form()-Funktion ausgegeben wird. Ab WordPress 4.4 wird hier die gewohnte Reihenfolge vertauscht und das Feld für den Kommentartext ganz oben stehen.

Der Code auf GitHub

Wie immer gibt es den Code im Repository auf GitHub. Den aktuellen Stand nach diesem elften Teil findet ihr unter dem Tag „v0.9“.

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