247 </ol> <?php else : // this is displayed if there are no comments so far ?> <?php if ('open' == $post->comment_status) : ?> <! if comments are open, but there are no comments > <p class="nocomments">Somebody say something!</p> <?php else : // comments are closed ?> <! if comments are closed > <p class="nocomments">Comments are closed.</p> <?php endif; ?> <?php endif; ?> That's all there is to it, really. Of course, like all things WordPress, there are a gazillion different ways to customize things, change the design, enhance functionality, and so on. Once you have threaded comments set up, they are easily styled with the following CSS selectors: .commentlist li.depth-1 {} .commentlist li.depth-2 {} .commentlist li.depth-3 {} /* and so on */ Reply-To for Non-JavaScript Users To accommodate those without JavaScript, replace your crusty old “Leave a Comment” text with something more dynamic by using this instead: <?php comment_form_title('Leave a Reply', 'Leave a Reply to %s'); ?> This tag will output “Leave a Reply” by default, but as soon as someone without JavaScript clicks to reply to a comment, the page refreshes and the output changes to “Leave a Reply to Whoever.” You can customize the text to whatever you want. The “%s” will dynamically output the name of the person being replied to. Threaded Plugins If your version of WordPress does not support threaded comments, upgrade. If upgrading is not on the menu, you can get threaded comments by using one of these ne plugins: http://digwp.com/u/186 http://digwp.com/u/187 http://digwp.com/u/188 http://digwp.com/u/189 248 You can then target any element for a specific comment level like so: .commentlist li.depth-1 div {} This CSS would target any <div> elements within any first-level comment. 7. 3.5 Separating Comments, Pingbacks, and Trackbacks When displaying the responses to your posts, an effective way to reduce the clutter and keep things organized is to separate the comments from the pingbacks and trackbacks. This not only keeps the conversation flowing smoothly, it also emphasizes the ping/trackback responses by displaying them in a continuous list. Even More Comments Styling The new comment-display functionality generates a ton of context-specific classes, making it easy to style your comments however you wish. Each comment is surrounded by an element (<li> by default) that will include the following classes, depending on page view: • 'comment', 'trackback', 'pingback' • 'byuser' for any registered user • 'comment-author-authorname' for specific registered user • 'bypostauthor' for comments by the post author • 'odd' and 'even' for odd and even numbered comments • 'alt' for every other comment • 'thread-odd', 'thread-even', 'thread-alt' for the top-level comment in a thread • 'depth-1', 'depth-2', 'depth-3', etc. applied according to the level of comment nesting 249 This is one of the oldest tricks in the WordPress book, and there are as many different ways to approach it as there are different comments.php files. Here is a method for separating comments and ping/trackbacks that is as widely applicable, adaptable, and flexible as possible. Thanks to the “type” parameter of the wp_list_comments() template tag, separating your comments, pingbacks, and trackbacks is a breeze. Here are some examples to give you a general idea. Once you see the pattern, you can set things up however you like. Separate comments from both pingbacks and trackbacks <h3>Comments</h3> <ol class="comments"> <?php wp_list_comments('type=comment'); ?> </ol> <h3>Pingbacks/Trackbacks</h3> <ol class="pingbacks-trackbacks"> <?php wp_list_comments('type=pings'); ?> </ol> Separate comments, pingbacks, and trackbacks <h3>Comments</h3> <ol class="comments"> <?php wp_list_comments('type=comment'); ?> </ol> <h3>Pingbacks</h3> 250 <ol class="pingbacks"> <?php wp_list_comments('type=pingback'); ?> </ol> <h3>Trackbacks</h3> <ol class="trackbacks"> <?php wp_list_comments('type=trackback'); ?> </ol> And finally, here is the code required to separate comments from pingbacks and trackbacks using the old-school, foreach loop: <h3>Comments</h3> <?php foreach ($comments as $comment) : ?> <?php $comment_type = get_comment_type(); ?> <?php if($comment_type == 'comment') { ?> Display Clean Pingbacks and Trackbacks When listing your pings using the default loop, you will see a link followed by a snippet of text from the page that pinged your post. These snippets can vary in size, and are difficult to control because you never know what to expect from them. Fortunately, we can clean up the default display of pings by removing the text snippet and listing only a nice, clean link back to the pinging site. To do this, we need to add the following callback function to your theme's functions.php file: // clean pingbacks and trackbacks function cleanPings($comment, $args, $depth) { $GLOBALS['comment'] = $comment; echo '<li>'.comment_author_link().'</li>'; } Then, add the required callback parameter to the wp_list_comments function like so: <?php wp_list_comments('type=pings&callback=cleanPings'); ?> Feature / Bury This simple plugin will allow you to click links from the front or back end to "feature" or "bury" a comment. This doesn't do anything by itself, but adds those class names to the comment <li> so you can style them appropriately. http://digwp.com/u/467 251 <div class="comment"> <p><?php comment_author_link(); ?></p> <?php comment_text(); ?> </div> <?php } ?> <?php endforeach; ?> <h3>Pingbacks/Trackbacks</h3> <ol> <?php foreach ($comments as $comment) : ?> <?php $comment_type = get_comment_type(); ?> <?php if($comment_type != 'comment') { ?> <li><?php comment_author_link(); ?></li> <?php } ?> <?php endforeach; ?> </ol> You will inevitably want to customize the markup, template tags, and other functionality, but the central technique is all there. We are segregating the previous single comment loop with two individual loops that target comments and ping/trackbacks, respectively. Within each of these two loops, we are testing for the comment type and only displaying the preferred type within each loop. Along the way, we season the script with some modest HTML markup to keep things readable on the page. Once you establish core functionality on your site, you should customize the code according to your needs. Keep 'em Separated As you can see, displaying comments and ping/ trackbacks separately helps keep your comments clean and organized. Otherwise, pingbacks and trackbacks get mixed up in your comment thread and ruin the conversation. 252 7.3.6 Eliminating Pingbacks and Trackbacks It may be impossible to stop people from linking to your site (and why would you want to?), but you don’t have to show their pingbacks and trackbacks on your site. At best, pingbacks are still used around the Web, but trackbacks are slowly going extinct. Most trackbacks are spam anyway, so there is good reason to stop them from showing on your site. Indeed, there are many sites that wish not to display their incoming pingbacks and trackbacks along with their comments, or anywhere else for that matter. If this sounds like you, there are several ways to go about it. Only Display Pingbacks/Trackbacks Markup if They Exist In the previous code example showing how to display separate comments, pingbacks, and trackbacks, the headings for each section will be displayed even if there are no responses. To prevent this from happening, we ensure that all ping/trackback-related code is displayed only if some ping/trackbacks actually exist. Here’s the code to do this: <?php if (!empty($comments_by_type['comment'])) : ?> <h3>Comments</h3> <ol class="comments"> <?php wp_list_comments('type=comment'); ?> </ol> <?php endif; ?> <?php if (!empty($comments_by_type['pings'])) : ?> <h3>Trackbacks/Pingbacks</h3> <ol class="pingbacks-trackbacks"> <?php wp_list_comments('type=pings'); ?> </ol> <?php endif; ?> 253 Disable ping/trackbacks from the Admin area In the Admin area, go to “Settings > Discussion” and uncheck the option for “Allow link notifications from other Weblogs.” This will disable pingbacks and trackbacks on your site for all posts going forward. This global setting may be overridden on a post-by-post basis by checking “Allow Pings” on the Post Write/ Edit page. Omit ping/trackbacks from the comments loop Using the wp_list_comments tag to display your comments, simply set the “type” parameter as described in section 7.3.2. With the following code, for example, no pingbacks or trackbacks will be displayed – only comments: <h3>Comments</h3> <ol class="comments"> <?php wp_list_comments('type=comment'); ?> </ol> Delete the wp-trackback.php file from the root directory This is a very effective way of permanently disabling pingbacks and trackbacks. It is a totally safe thing to do, just remember to re-delete the file after upgrading WordPress. Globally disabling via plugin To globally disable trackbacks only, we can use Viper007Bond’s Disable Trackbacks plugin http://digwp.com/u/37. Since this is a very simple plugin, we can just add it to our active theme’s functions.php file (code modified/formatted for clarity): Save the Juice Pingbacks may represent a reciprocal linking affair, but trackbacks are generally free links to the referring site. Why waste the juice on a site that can't spare an actual link? 254 // Disable Trackbacks http://digwp.com/u/37 class DisableTrackbacks { // initialize plugin function DisableTrackbacks() { add_action('pings_open', array(&$this, 'pings_open')); } // if trackback, close pings function pings_open($open) { return ('1' == get_query_var('tb')) ? FALSE : $open; } } // load after all other plugins add_action('plugins_loaded', create_function('', 'global $DisableTrackbacks; $DisableTrackbacks = new DisableTrackbacks();')); Once in place, the DisableTrackbacks function will effectively eliminate all trackbacks from registering with your site. To ensure that no existing trackbacks are displayed, you should also omit them from the comment loop as described in the previous section. Note that pingbacks will still be processed even with the Disable Trackbacks script in place. 7.3.7 Control Comments, Pingbacks, and Trackbacks Directly with the Database WordPress provides several ways of controlling which posts are open to comments, pingbacks, and trackbacks. In the Admin Settings Discussion area, you can disable all responses on a sitewide basis for all future comments. You may also control responses for each post via the “Discussion” panel in the post-management screen. 255 Beyond these methods, you can either use a plugin such as the Auto Moderate Comments plugin http://digwp.com/u/38, or else save time and effort by simply querying the database directly. Querying the database is a great way to control responses on existing posts. Here is a collection of quick, copy-&-paste SQL recipes for controlling comments, pingbacks, and trackbacks: Globally enable pingbacks/trackbacks for all users UPDATE wp_posts SET ping_status = 'open'; Globally disable pingbacks/trackbacks for all users UPDATE wp_posts SET ping_status = 'closed'; Globally disable pingbacks/trackbacks before a certain date For this query, specify the ping_status as either open or closed. Also, specify the date by editing the date, “2009-09-09”, to suit your needs. UPDATE wp_posts SET ping_status = 'closed' WHERE post_date < '2009-09-09' AND post_status = 'publish'; Complete, one-step discussion management Given the queries described above, we may fashion the following “one-step” SQL queries, perfect for complete, plugin-free discussion management: Globally enable/disable all discussion: comments, pingbacks and trackbacks For this query, specify the comment_status as either open, closed, or registered_only. Also, specify the ping_status as either open or closed. UPDATE wp_posts SET comment_status = 'open', ping_status = 'open' WHERE comment_status = 'closed' AND post_status = 'publish'; Back that DB Up! Before running any SQL queries or doing any other work on your database, remember to make a backup copy or two. The database stores all of your information and data – it would suck royally to lose it. Quick and Easy These SQL queries are perfect for managing discussion a few times a year without using another plugin. 256 Globally enable/disable comments, pingbacks and trackbacks before a certain date For this query, specify the comment_status as either open, closed, or registered_only. Also, specify the ping_status as either open or closed. Finally, specify the date by editing the “2009-09-09” to suit your needs. UPDATE wp_posts SET comment_status = 'closed', ping_status = 'closed' WHERE post_date < '2009-09-09' AND post_status = 'publish'; 7.4.1 Customizing Comment Display Even if your theme is already configured to display comments in a useful and visually appealing way, there is always something that may be improved. In this section, we’ll show you some awesome ways to completely trick out the visual presentation of your WordPress comments area. 7.4.2 Numbering Comments Globally and Locally There are basically two different ways to number your comments: globally and locally. Global numbering of comments happens automatically as comments are added to the WordPress database. The number of each comment on your site represents its position within the comments database table. Global comment numbers are called via the comment_ID template tag. This tag may be used to identify individual comments with their associated comment ID, like so: <a href="#comment-<?php comment_ID(); ?>" id="comment-<?php comment_ID(); ?>">Permalink for this comment</a> Identifying each comment with its global ID via the markup makes it easy for people to refer and link to any specific comment on your site. And, while you may also label each comment as it appears on the page with its corresponding global ID, you may want to use local numbering of comments instead. Why? . comment • 'thread-odd', 'thread-even', 'thread-alt' for the top-level comment in a thread • 'depth-1', 'depth-2', 'depth-3', etc. applied. the following CSS selectors: .commentlist li.depth-1 {} .commentlist li.depth-2 {} .commentlist li.depth-3 {} /* and so on */ Reply-To for Non-JavaScript Users To accommodate those without JavaScript,. date, “200 9-0 9-0 9”, to suit your needs. UPDATE wp_posts SET ping_status = 'closed' WHERE post_date < '200 9-0 9-0 9' AND post_status = 'publish'; Complete, one-step