Für Menschen · Seien Sie begeistert und Sie werden begeistern !
Seit WordPress 2.7 gibt es eine API für den Bereich der Kommentare. Damit kann man auch den PHP-Anteil innerhalb der comments.php entschlacken, je nach eigenem Ermessen. Jean-Baptiste zeigt eine einfache Lösung, um die Kommentare zu zählen. Die Lösung sollte bekannt sein und wird quasi seit der ersten WordPress Veröffentlichung so realisiert. Hinweise dazu gibt es vielfach hier im Blog und im Netz. Wollte man dann aber einen Filter über den Zähler haben, der beispielsweise nur die Trackbacks zählt oder auch nur die Kommentare, die per Formular eingehen, dann scheitert diese Lösung. Außerdem ist das How To doch recht schmal und PHP-Laien könnten in Schwierigkeiten geraten.
Aus diesem Zusammenhang und diverser Fragen zum Thema zeige ich mal zwei einfache Funktionen, die in der functions.php des Themes abgelegt werden und dann willkürlich im Theme genutzt werden können. In der Regel werden sie dann also zur Ausgabe in der comments.php heran gezogen.
/**
* count for Trackback, pingback, comment, pings
*
* so einbinden:
* fb_comment_type_count('ping');
* fb_comment_type_count('comment');
*/
if ( !function_exists('fb_comment_type_count') ) {
function fb_get_comment_type_count( $type='all', $zero = false, $one = false, $more = false, $post_id = 0) {
global $cjd_comment_count_cache, $id, $post;
if ( !$post_id )
$post_id = $post->ID;
if ( !$post_id )
return;
if ( !isset($cjd_comment_count_cache[$post_id]) ) {
$p = get_post($post_id);
$p = array($p);
update_comment_type_cache($p);
}
;
if ( $type == 'pingback' || $type == 'trackback' || $type == 'comment' )
$count = $cjd_comment_count_cache[$post_id][$type];
elseif ( $type == 'pings' )
$count = $cjd_comment_count_cache[$post_id]['pingback'] + $cjd_comment_count_cache[$post_id]['trackback'];
else
$count = array_sum((array) $cjd_comment_count_cache[$post_id]);
return apply_filters('fb_get_comment_type_count', $count);
}
// comment, trackback, pingback, pings, all
function fb_comment_type_count( $type='all', $zero = false, $one = false, $more = false, $post_id = 0 ) {
$number = fb_get_comment_type_count( $type, $zero, $one, $more, $post_id );
if ( $number > 1 )
$output = str_replace('%', number_format_i18n($number), ( false === $more ) ? __('% Comments') : $more);
elseif ( $number == 0 )
$output = ( false === $zero ) ? __('No Comments') : $zero;
else // must be one
$output = ( false === $one ) ? __('1 Comment') : $one;
echo apply_filters('fb_comment_type_count', $output, $number);
}
}
if ( !function_exists('fb_update_comment_type_cache') ) {
function fb_update_comment_type_cache(&$queried_posts) {
global $cjd_comment_count_cache, $wpdb;
if ( !$queried_posts )
return $queried_posts;
foreach ( (array) $queried_posts as $post )
if ( !isset($cjd_comment_count_cache[$post->ID]) )
$post_id_list[] = $post->ID;
if ( $post_id_list ) {
$post_id_list = implode(',', $post_id_list);
foreach ( array('', 'pingback', 'trackback') as $type ) {
$counts = $wpdb->get_results("SELECT ID, COUNT( comment_ID ) AS ccount
FROM $wpdb->posts
LEFT JOIN $wpdb->comments ON ( comment_post_ID = ID AND comment_approved = '1' AND comment_type='$type' )
WHERE post_status = 'publish' AND ID IN ($post_id_list)
GROUP BY ID");
if ( $counts ) {
if ( '' == $type )
$type = 'comment';
foreach ( $counts as $count )
$cjd_comment_count_cache[$count->ID][$type] = $count->ccount;
}
}
}
return $queried_posts;
}
add_filter('the_posts', 'fb_update_comment_type_cache');
}
Sind die beiden Funktionen abgelegt und damit im Theme verfügbar, so könnte die Nutzung für die drei Formen comments, trackbacks und pingbacks zum Beispiel wie folgt aussehen.
if ( function_exists('wp_list_comments') ) {
// WP 2.7 Kommentar Loop
if ( have_comments() ) { ?>
<?php if ( empty($comments_by_type['comment']) ) { ?>
<h2 id="comments"><?php fb_comment_type_count( 'comment' ); ?></h2>
<ol class="commentlist">
<?php wp_list_comments( 'type=comment&callback=fb_theme_comment' ); ?>
</ol>
<?php } ?>
<?php
if ( function_exists( 'fb_comment_type_count' ) ) {
// alternativ type pings fuer trackback + pingback
if ( empty($comments_by_type['pingback']) ) { ?>
<h2 id="pingback"><?php fb_comment_type_count( 'pingback', 'Keine Pingback', 'Ein Pingback', '% Pingbacks' ); ?></h2>
<ol class="pingbacklist">
<?php wp_list_comments('type=pingback'); ?>
</ol>
<?php } ?>
<?php
// alternativ type pings fuer trackback + pingback
if ( empty($comments_by_type['trackback']) ) { ?>
<h2 id="trackback"><?php fb_comment_type_count( 'trackback', 'Keine Trackback', 'Ein Trackback', '% Trackbacks' ); ?></h2>
<ol class="trackbacklist">
<?php wp_list_comments('type=trackback'); ?>
</ol>
<?php }
} ?>
<div class="navigation nav_comments">
<div class="alignleft"><?php previous_comments_link() ?></div>
<div class="alignright"><?php next_comments_link() ?></div>
</div>
<?php } else {
// this is displayed if there are no comments so far
} ?>
Die obige Syntax zeigt nur einen Ausschnitt aus der comments.php und sollte daher in die jeweilige Anforderung eingepasst werden. Im Basis-Theme von mir ist es aktuell nicht drin, kommt aber.
Die obigen Bereiche können natürlich mit anderem Markup ausgestattet werden und die Klassen und IDs sind auch nur beispielhaft. Da sind die Möglichkeiten jedem überlassen und den eigenen Anforderungen anzupassen.
Hinweise, Lob, Verbesserungen oder Kritik - die Kommentare stehen euch wie immer offen, auch wenn die meisten ja eher per Feed hier mitlesen.
Ich bin urlaubsreif, ersticke in Arbeit und damit auch für die Leser des Weblogs nicht zu erreichen. Bitte geduldet euch ein wenig mit Supportanfragen.
Leider muss ich die Kommentarfunktion deaktivieren, ansonsten würde ich weiter in Arbeit ersticken oder die Anfragen nicht nach bestem Gewissen beantworten.
Vielen Dank für das Verständnis!
bueltge.de [by:ltge.de] wird von Frank Bültge geführt, administriert und gestaltet. Alle Inhalte sind persönlich von mir ausgewählt und erstellt, nach bestem Gewissen und Können, was die Möglichkeit von Fehlern nicht ausschließt.
Das Weblog wird angetrieben von WordPress und aktuell gibt es 854 Beiträge, 15036 Kommentare in 14 Kategorien und 450 Tags.
Das Blog wird liebevoll mit xHTML & CSS in Handarbeit gestaltet.
Design und Code ist unter Copyright
© 2001 - 2010 bueltge.de [by:ltge.de]
3. Februar 2009 um 17:16
Super, genau danach war ich gestern auf der Suche. Danke für diese Lösung!
4. Februar 2009 um 17:07
Hi,
ich würde gerne die Pingbacks/Trackbacks etwas anders darstellen, wenn ich
aufrufe zeigt er mit 2x mal den "Author" an und und noch content.
ich würde gerne nur den "Auhtor" mit Link zum Trackback/Pingback anzeigen.
Ich werde einfach aus dem ganzen nicht so recht schlau.
4. Februar 2009 um 19:26
Das obige Beispiel soll auch nur den EInbau des Zähler verdeutlichen, die Links etc. werden mit den gängigen Template Tags von WP erstellt.
5. Februar 2009 um 08:52
Hi,
um das Beispiel oben aber richtig nutzen zu können macht es Sinn das ergänzend zu posten. Dieses Beispiel hab ich ja auch schon x-mal im Web gefunden, aber nie den Punkt zur Darstellung dazu.
Wenn ich das richtig gesehen habe müsste man wp_list_comments mit einer Callback Funktion aufrufen um das Layout anpassen zu können. Ich habs aber nicht hinbekommen. Auch wenn ich schon einigene kleine Plugins geschrieben hab bekomm ich das nicht ganz auf die Reihe. Bin noch ziemlich frisch im WP Bereich.
5. Februar 2009 um 09:25
Schau dir mal den Code meiner Sandbox an; ab 2.7 muss zusätzlich ein Eintrag in der
header.phpsein, um die threaded comments zu ermöglichen. Ich vermute, dort siehst du es klarer, da diecomments.phpmit allen Inhalten da ist. Ansonsten muss ich mal Zeit finden und ein kleines Tutorial erstellen.5. Februar 2009 um 09:55
Ah ja, vielen Dank.
Das ist doch mal ein Beispiel das man umsetzen kann.
Funktioniert jetzt wunderbar, Danke Frank!
6. Februar 2009 um 19:44
Ich habe in meinem theme dkret3 gerade die Unterstützung eines neuen Plugins eingebaut. Gregs Threaded Comments Numbering bietet eine wunderbar einfache und komfartable Möglichkeit, Kommentare zu nummerieren.
Außerdem werden Unterkommentare entsprechend gezählt (1.1 etc.). Wirklich ein tolles Plugin.
8. Februar 2009 um 01:09
Danke für die ausführliche Anleitung! Mal sehen ob ich damit zurecht komme.
Gruß
Mobe
9. Februar 2009 um 14:54
Hi Frank, ich hab Dein Beispiel für den Kommentarzähler mal bei mir ausprobiert und bis auf eine Kleinigkeit funktioniert das auch. Ich würde gerne die Kommentare getrennt gezählt haben. Als Beispiel: Es liegen zwei Pingbacks, ein Trackback und drei Kommenatre vor. Die Tracks und Pings werden mit dem obigen Codeschnipsel richtig gezählt, nur bei den Kommentaren steht im Zähler "6" anstatt "3" ... wie muss ich das ändern um die "normalen" Comments getrennt zu zählen?
9. Februar 2009 um 14:57
$type == 'comment'ist der Schlüssel. Du kannst also die obige Funkion nutzen und mit Übergabe des Paramter $type den Typ mitgeben, in dem Fall comment.9. Februar 2009 um 15:03
Hi,
bei mir hab ich das "getrennte Zählen" wie folgt gelöst:
/** * Funktion zum zählen der Comments und Pingbacks */ add_filter('get_comments_number', 'comment_count', 0); function comment_count( $count ) { global $id; $comments_by_type = &separate_comments( get_comments('post_id=' . $id) ); return count($comments_by_type['comment']); } function pings_count( $count ) { global $id; $comments_by_type = &separate_comments( get_comments('post_id=' . $id) ); return count($comments_by_type['pings']); }9. Februar 2009 um 15:21
alles klar, habs gerade hinbekommen, was mich in diesem Zusammenhang interessieren würde ist die Ausgabe. Wenn man comments_number nutzt lässt sich die Ausgabe variabel gestalten, also Ein Kommentar, 5 Kommentar(e) bzw. Kein Kommentar als Beispiel. Lässt sich sowas auch für Deine Funktion "fb_comment_type_count" realisieren?
Auf jeden Fall erstmal Danke für die schnelle Antwort und Respekt für Deine mehr als hilfreiche Seite die wirklich klasse Beiträge bereit hält! Grüße, Markus
9. Februar 2009 um 20:34
@Markus: danke für den Hinweis, dass hatte ich damals nicht vorgesehen und nun habe ich es ergänzt. Man hat nun mehr Parameter und ich habe es nicht als reine Ausgabe realisiert, sondern via Filter, wie es WordPress auch macht.
@alle: Bitte schaut euch das Update des COde an, es bietet mehr Möglichkeiten.
9. Februar 2009 um 21:35
@Markus:
Bei mir sieht das so aus:
comments_popup_link(__('Kommentare (0)'), __('Kommentar (1)'), __('Kommentare (%)'));10. Februar 2009 um 23:27
was für ein Service! Klasse Frank, ich bin ja begeistert ... Ich erstelle zwar selbst Webseiten und Wordpress-Templates aber was Funktionsprogrammierung angeht bin ich froh, dass es Leute wie Dich gibt die mit Ihrem Know-How weiterhelfen. Ich baue gerade an einem Theme, dass nach Möglichkeit alle wesentlichen Funktionen der neuen Wordpress-Version nutzt aber wenn ich mir Dein Basis-Template anschaue geht da noch ne ganze Menge mehr. Die Kommentargeschichte ist ja im neuen WP ein wenig zweischneidig. Auf der einen Seite wird manches vereinfacht, auf der anderen Seite wirds doch wieder komplexer sofern man die Comments wirklich individuell stylen möchte ... auf jeden Fall hat mich Dein Beispiel hier schon ne ganze Ecke weitergebracht ...
@ BongoUser: Danke für den Tipp, ich hoffe das ich irgendwann mal alle Template-Tags im FF parat habe, den comments_popup hatte ich bisher noch garnicht auf dem Schirm ... beste Grüße, Markus
19. Februar 2009 um 13:02
Danke für den Tipp jetztmkann ich endlich auch auf WP 2.7 updaten.
4. März 2009 um 14:48
Hallo Frank,
ich habe die getrennte Zählung gemäß deinem Beispiel und dem Code aus der Sandbox nun auch bei mir realisiert. Ist es noch möglich den Code für die Hervorhebung der Kommentare des Blogbetreibers? Bis jetzt benutzte ich immer folgenden Code:
<li id="comment-"comment_author_email == get_the_author_email()) && ($comment->user_id != 0) ) {
echo " class=\"autor_kommentar\"";
} else {
echo " class=\"" . $oddcomment . "\"";
}
?>>
Leider funktioniert das nicht wie gewünscht, hast du eine Lösung?
4. März 2009 um 19:52
Ich übergebe beim Aufruf von
wp_list_comment()eine Funktion mit, welche sich um die Ausgabe der Kommentare kümmert. Ist auch so in der Sandbox:<?php if ( empty($comments_by_type['comment']) ) { ?><?php fb_comment_type_count( 'comment' ); ?>
<?php wp_list_comments( 'type=comment&callback=fb_theme_comment' ); ?>
<?php } ?>Diese Funktion hat eine neue Funktion im li-Tag:
comment_class():Diese vergibt die entsprechenden Klassen, so dass ich das Abfragen wie du es zeigst, gar nicht machen muss. Ich habe damit die Klasse
authorbzw.bypostauthordabei und die formatiere ich dann entsprechend.6. März 2009 um 11:21
Vielen Dank für den Hinweis, die Funktion kannte ich noch gar nicht. Habe sie jetzt aber implementiert. Doch gleich das nächste Problem, eine leere Weiße Seite wenn ich ein Kommentar abschicke, egal ob ein Angemeldeter oder nicht angemeldeter Benutzer das macht, sowohl bei FF als auch beim IE. Offenbar kommt kein Rücksprung von der wp-comments-post.php - ob es an dem Formular liegt? Ich kann keinen Fehler entdecken.
6. März 2009 um 11:31
@Robert: meist liegt es an der
comments.phpdes Themes, da fehlt dann was.6. März 2009 um 11:59
Kurioserweise habe ich Testhalber jetzt die Funktion fb_theme_comment, fb_comment_type_count und fb_update_comment_type_cache aus deiner Sandbox übernommen. Die comments.php habe ich zu Testzwecken ebenfalls durch die aus der Sandbox 1:1 ersetzt. Der Fehler bleibt aber der gleiche.
Das Kommentar wird zwar eingetragen und erscheint auch beim erneuten Seitenaufruf, aber die leere Seite wird weiterhin angezeigt und springt nicht zurück.
6. März 2009 um 12:17
sauberes WordPress?, geht es mit dem default-Theme; meine Sandbox klappt im Test
6. März 2009 um 12:47
Gute Idee, ein anderes Theme, dasselbe Problem. Plugins deaktiviert und probiert. Aha! Ich sollte noch einen Kaffee trinken, der Comment Mailer hat einfach keine Eingabe erhalten, weil ich das entsprechende Feld noch nicht eingefügt hatte. Wie peinlich!
Du kannst diese Kommentare gerne löschen
6. März 2009 um 13:30
Wunderbar, dann passte es ja nun. Viel Erfolg.
Kaffee - ah ja, ich nun auch mal.
7. März 2009 um 00:11
EIne Frage ergibt sich jetzt doch noch. Wenn die Abfrage kein Pingback vorfindet, gibt es trotzdem ein leere und damit nicht valide Liste aus. Kann man die Abfrage nicht so modifizieren, das sie im Falle keiner Pingbacks auch nichts ausgibt (auch keine Überschrift)?
7. März 2009 um 11:23
if ( empty($comments_by_type['pingback']) ) {Das fragt ab, ob es pingbacks gibt, wenn nein, dann wird auch nichts ausgegeben.
7. März 2009 um 18:04
Davon bin ich auch ausgegangen, leider funktioniert das offenbar nicht. Der Code im Zusammenhang:
if ( empty($comments_by_type['pingback']) ) { ?>Leider bekomme ich als Ausgabe immer die Überschrift und eine leere Tabelle. Ist das vielleicht ein php 4/5 Problem?
8. März 2009 um 12:28
nein, empty ist kein PHP5 Problem und hier wird nur gefragt, ob es Einträge gibt, sonst gib nix aus, was in meinen Tests auch sauber klappt.
15. März 2009 um 15:50
Hi Frank, ich kann das kleine Problem von Robert bestätigen. Sofern keine Tracks oder Pings vorhanden sind wird sowohl die Headline "Keine Trackback" bzw. "keine Pingback" ausgegeben als auch eine leere Liste (ol class pingbacklist bzw. ol class trackbacklist) ... Ich hab sowohl Deine Oiginal-comments.php als auch die functions.php des Basis-Themes probiert als auch den Code aus diesem Beitrag hier, das Ergebnis ist immer eine leere OL wenn keine Tracks oder Pings vorhanden sind ... Grüße, Markus
16. März 2009 um 11:23
@Markus: ok, schaue es mir nochmal an; eventuell reicht es wenn man die Prüfung negiert, mit
!empty($comments_by_type['pingback']).16. März 2009 um 19:55
Danke Frank, das wars schon ... mit der Negierung funktioniert es. Bin gerade über dem Styling meiner Kommentare im neuen Template und gleich über eine weitere Sache gestolpert: Wie lassen sich die Kommentar-Nummern ausgeben? Mit der alten Kommentarfunktion ging das per php foreach ($comments as $comment) : $comment_count++; und dann an geeigneter Stelle per "echo count" ... das lässt sich doch bestimmt auch in Deiner Funktion einbauen, hab leider zu wenig Planung von PHP um da selbst rumzuschrauben
19. März 2009 um 10:48
Noch ein Nachtrag: Beim Bau meines Themes ist mir aufgefallen, dass bei Nutzung einer individuellen Ausgabe der Kommentare per Callback grundsätzlich ein schließendes /li ausgeben wird. Am Beispiel Deiner Funktion fb_theme_comment bedeutet das, dass man das schließende /li nicht notiert da Wordpress diese aus irgendeinem Grund bereits selber ausgibt, ansonsten endet die Ausgabe mit zwei /li´s (WP-Bug?)
Greets, Markus
19. März 2009 um 11:05
@Markus: stimmt, habe ich auch bemerkt, wollte es aber noch prüfen. Finde es sehr komisch.
29. Juni 2009 um 17:59
Ich hab das jetzt auch mal so eingebaut und hab bisher auch das Problem, dass bei der Kombination kein Trackback/Kommentar das ol Tag der Trackbacks angezeigt wird. Aber mir ist auch nicht so ganz klar, wieso die Abfrage empty($comments_by_type['trackback']) nicht negiert sein muss (obwohl dann entsprechend gar nichts angezeigt wird). Das Array sollte doch gerade nicht leer sein, damit der Fall eintritt. Gibt es da evtl. eine andere Möglichkeit abzufragen, ob Trackbacks/Kommentare vorhanden sind?
Nebenbei: Das schließende /li Tag kommt durch die integrierte reply Funktion. Antwortet man auf ein Kommentar, wird dieser innerhalb des li Tags eingebunden.
3. August 2009 um 16:43
Hello,
I have some problems with reference from fb_update_comment_type_cache function with PHP 5.3.0.
It works fine without it but I don't really know the utility of that function.
Hope you speak english,
Alex
3. August 2009 um 17:37
@Alex: this function is only for reset the cache of WordPress when it add a comment.
3. August 2009 um 17:44
Thanks for quick answer.
And what's happen when I remove & from
function fb_update_comment_type_cache(&$queried_posts)
There is some incompatibility with reference in PHP 5.3.0
Regards,
Alex
3. August 2009 um 18:51
Yes, you can delete this function, include the filter.
4. August 2009 um 21:53
Another problem, does not seem to work on attachments. Did you know about this or it's just me?
Also, update_comment_type_cache() does not exists, it's fb_update_comment_type_cache() right?
Regards,
Alex
5. August 2009 um 10:18
@Alex: yes, this is the correct function. Please see the WP Basis Theme, i use this function on this theme and you can read and use the syntax.
5. August 2009 um 11:13
Thanks for the elucidation.
Any clues about that attachments problem?
Regards,
Alex
5. August 2009 um 14:20
@Alex: do you men the attachment-Template?
5. August 2009 um 14:53
Not really, the attachment default template is single.php
For example on posts (single.php) comments/trackbacks number are displayed but on attachments (same template - single.php) are not.
5. August 2009 um 21:17
Any ideas?
6. August 2009 um 08:37
@Alex: i dont understand the problem with the attachments; please can you write more infos. My functions are filter for track-, pingbacks and comments, not attachments. Sorry and i hope you can send me your wish.
6. August 2009 um 10:30
Yes, but you can add comments to attachments right?
This is my problem.
echo fb_get_comment_type_count('comment') ---- does not display anything on attachment page.
6. August 2009 um 12:47
@Alex: ok, also the attachment-Template or the default template with a attachment. I will test this and write a solution.
28. Dezember 2009 um 02:29
Hallo Frank,
beim studieren deienes Codes ist mir die gleiche Frage wie bei Mark (#31) aufgekommen.
Viele Grüße,
Vlad
2. Januar 2010 um 11:07
@Perun: im Code habe ich das aktuell nicht drin, in einer anderen Seite mache ich das via JS, da es nur dann Mehrwert ist, wenn JS aktiv ist:
<script type="text/javascript">
//<![CDATA[
document.documentElement.className += " js";jQuery(document).ready( function($){var li=$('#kommentarbereich .tabs').size();if(li==2){$('#kommentarbereich').accessibleTabs({tabhead:"h6",tabbody:".tabs",fx:"fadeIn"});}$('.commentlist li').each(function(i){$(this).prepend('<span class="co-number">'+(i+1)+'<\/span>');})});
//]]>
</script>
Der Schnippsel steht im Footer oder wird extern geladen, benötigt jQuery.