Let’s face it, the Twitter search sucks and you’ll be lucky to find tweets over a week old with it even though they still exist.
Twitter has been plagued with service issues and the fail whale (which someone coded in pure CSS) is a regular occurrence once again.
I came across a tutorial the other day on how to create a browsable, searchable archive of tweets which you can use to host your own tweets. And the best part is? It’s powered by WordPress.
In this article, I’ll go over my experience with how I set up my own @themelab tweet archive powered by WordPress, including:
The first step is to backup your tweets. There are a few third-party services to do this, I personally used TweetBackup with good success. It’s important to remember not to expect to backup all of your tweets.
I was only able to grab 910 out of over 6000+ at the time. Even using other Twitter backup services, the same number of tweets were backed up which suggests it’s a limitation by Twitter itself. It’s best to backup as soon as possible, especially if you’re a frequent tweeter.
I had some issues logging into TweetBackup at first but eventually it worked. If you get frustrated you could also try BackupMyTweets.com. It’s worth noting that BackupMyTweets makes you “pay” by posting a tweet promoting their service. If that’s too painful for you (it’s pretty painless, I promise) you also have the option of paying $9.95 per year.

After the backup process is complete, look for the “export” option and save as RSS. You should have an XML file with all the tweets that were salvageable. The next step is to import those into WordPress.
First of all, it’s suggested you create a new WordPress installation for your tweet archive so you don’t have to worry about separating it from the rest of your normal WordPress content. I personally used a subdomain so it wouldn’t interfere with any permalinks from the blog.
The next step is to browse to Tools→Import and select the “RSS” option.

On the next screen, upload the XML file you just grabbed from whatever tweet backer-upper service you just used. Your tweets should now be loaded in your WordPress site.
Now that you have all your old tweets stored, you’ll want to make sure any new tweets are automatically grabbed and stored as WordPress posts. For this, we’ll be using the Twitter Tools plugin by Alex King.
After installing and verifying your Twitter account details, make sure the following two options are set on the plugin’s settings page (Settings→Twitter Tools):

I’m not sure what would happen if you set “Yes” to both, but I don’t intend on finding out for myself for fear of annoying the crap out of my followers. Douglas Bownman, the author of the original guide, described it as an “endless loop of repeating tweets and blog posts.”
All of the other options, like whether to exclude @replies, are either not necessary or up to your personal preferences.
Note: After installing Twitter Tools I noticed a few duplicate tweets (in conjunction with my backed-up tweets) that I went back and manually deleted.
Douglas Bownman of stopdesign was also nice enough to release the tweet archive theme he used for free.

The theme works out of the box but it requires some *gasp* direct theme editing to personalize the hard-coded area (that I’ve highlighted in red) with your own account information. Just open up your header.php and scroll to the bottom.

Make sure you have the following handy to copy and paste into the “user” div area in the header file:
Or you could just remove it completely, it’s up to you. There is also a nice display of archive links which don’t seem as dreaded on an archive-oriented site like this.
If you’re making your own custom theme make sure to display the post content and have the full date and time as the permalink to the post. I’m not sure comments are really necessary on a theme like this, but again, it’s your site now, so you can do whatever you want with it.
Update: I just noticed the search form had the /tweets/ URL hardcoded into the form action, which obviously won’t work if you’ve installed anywhere besides a /tweets/ subdirectory. To correct this, replace the following code in searchform.php:
<form method="get" id="searchform" action="/tweets/">
And replace with:
<form method="get" id="searchform" action="<?php bloginfo('url'); ?>/">
I really wish I set this up a long time ago. I’m a Twitter addict and have over 6000 tweets (follow me at @themelab) and unfortunately I wasn’t able to back all of them up, only about 15% of them.
Once again I’d like to thank Douglas Bowman of stopdesign for the guide on settings this up as well as the theme. It was actually a lot easier than I thought and it’s great that it can be powered by my favorite CMS, WordPress, with the help of some extra plugins.
Related posts:
If you’re not familiar with the WP-PageNavi WordPress plugin, it allows you to replace normal previous/next navigation with a more advanced, numbered paging navigation. This is a feature I’ve included on a number themes I’ve developed, including RS16, Blogwave, RS17, and Bright Spot.
In this tutorial, I’m going to go over how to:
You have two options when it comes to installing the WP-PageNavi plugin.
/wp-content/plugins/ directory, and activate (aka, the old fashioned way).Okay, that should’ve been pretty easy. Now it’s time to get your hands a little dirty in code for the integration part.
In our theme integration, we never want any errors to be displayed if the WP-PageNavi isn’t active. Instead, we’ll make sure it falls back on the old previous/next-style navigation. To do this, we’ll use a function_exists conditional check.
Let’s say this is your normal previous/next WordPress navigation code:
<div class="navigation">
<div class="alignleft"><?php next_posts_link('« Older Entries') ?></div>
<div class="alignright"><?php previous_posts_link('Newer Entries »') ?></div>
</div>
We will change it to the following:
<?php if (function_exists('wp-pagenavi')) { wp_pagenavi(); } else { ?><div class="navigation">
<div class="alignleft"><?php next_posts_link('« Older Entries') ?></div>
<div class="alignright"><?php previous_posts_link('Newer Entries »') ?></div>
</div><?php } ?>
This basically checks to see if WP-PageNavi is active and if it is, it displays the new page navigation code. If not, it gracefully falls back to the normal previous/next navigation.
Please Note: Depending on how your CSS is coded, you may want to put the wp_pagenavi(); part inside the “navigation” (or equivalent) div. Keep in mind WP-PageNavi spits out a new class called “wp-pagenavi” though which we can use to style separately.
By default, WP-PageNavi automatically inserts a CSS file called pagenavi-css.css from its plugin directory into the header of your site. We don’t want these default styles to interfere with our own cool custom-made styles, so we’ll completely get rid of them, and there are two simple ways to do just that.
add_action( 'wp_print_styles', 'my_deregister_styles', 100 );
function my_deregister_styles() {
wp_deregister_style( 'wp-pagenavi' );
}
Just plop that code in your theme’s functions.php file and add the CSS styles to your regular theme’s stylesheet (usually style.css).
Note: Make sure the code is surrounded by brackets like <?php ... ?> if your functions file is currently empty.
Here’s what the WP-PageNavi markup looks like. In the following example, there are four pages, currently on page two.
<div class="wp-pagenavi">
<a href="http://example.com/" >Previous</a><a href="http://example.com/" class="page" title="1">1</a>
<span class="current">2</span>
<a href="http://example.com/?paged=3" class="page" title="3">3</a>
<a href="http://example.com/?paged=3" >Next</a></div>
<span class="extend">...</span>
<a href="http://example.com/?paged=4" class="last" title="Last »">Last »</a>
</div>
We can use the following CSS selectors to target the above HTML markup:
.wp-pagenavi – Applies to the entire div, useful for CSS clears, padding/margin, font sizes and styles (bold, italic, etc.).wp-pagenavi a – Targets all links inside the page navigation, including page numbers and previous/next..wp-pagenavi a.page – Targets page numbers specifically.wp-pagenavi a.first – Targets the “first” link specifically (not listed above).wp-pagenavi a.last – Targets the “last” link specifically.wp-pagenavi span – Targets the current page number along with the extend part (the thing with three dots).wp-pagenavi span.current – Specifically targets the current page number.wp-pagenavi span.extend – Specifically targets the extend (three dots thing).wp-pagenavi span.pages – Specifically targets page number display (i.e. Page 1 of 4)Note: The previous and next links by default, have no CSS class on them. If you want them to completely differentiated from the page numbers and first/last links, those will need to reset any styles added to the .wp-pagenavi a selector. If that made no sense, take a look at the following (really simplified) example.
For example: Let’s say you wanted the the previous and next links to be bold, but every other link to have a normal weight. You would need to do the following:
.wp-pagenavi a { font-weight: bold; } /* Previous and Next links only */
.wp-pagenavi a.page,
.wp-pagenavi a.first,
.wp-pagenavi a.last { font-weight: normal; } /* Other links */
I combined page number links, the first link, and the last link into one rule for example purposes. Of course, you can separate them and add more specific styles to each one.
This would be much easier if there was a class added to previous/next links by default, but there’s not. It’s not a huge deal as you can just reset them anyway.
Important Update: Thanks to an update from scribu in the comments, it turns out the newest version of WP-PageNavi does have previous/next classes on them (thanks in part to Yoast).
You can use .wp-pagenavi a.previouspostslink and .wp-pagenavi a.nextpostslink to select previous and next links, respectively.
So pretty much everything above up until the unordered list of selectors isn’t relevant anymore, but I’ll keep it just because it could be a useful lesson in overriding CSS in some other situations. The below CSS example will still apply as I didn’t use those selectors anyway.
Here’s an example of a PageNavi styling which I built off of the Blogwave theme.

Here’s the code I used to get this look, multi-single-line CSS is optional:
.wp-pagenavi a, .wp-pagenavi span {
padding: 5px; margin-right: 10px;
font-size: 15px; color: #03719c; text-decoration: none;
border: 3px solid #ccc; -moz-border-radius: 5px; -webkit-border-radius: 5px; border-radius: 5px;
}
.wp-pagenavi a:hover, .wp-pagenavi span.current {
background: #03719c;
color: #fff;
border: 3px solid #AFAFAF;
}
.wp-pagenavi span.current { font-weight: bold; }
And here’s what it all means:
First Rule
The .wp-pagenavi a, .wp-pagenavi span selects all anchor and span elements (pretty much everything) inside the .wp-pagenavi div.
border-radius code makes the corners rounded.Second Rule
The .wp-pagenavi a:hover, .wp-pagenavi span.current selects the link hover effect as well as the current page number, respectively.
Third Rule
This selects the current page number (again) without affecting the link hover effect as well (like the second rule). This just makes the current page number a bold font weight.
The reason I didn’t include it with the link hover effect is because it has an uneven effect going from normal to bold font weight.
Note: Depending on how your CSS is coded, you may have to use more specific selectors. For example, if there are styles for #content a and your WP-PageNavi is inside the content div, you may have to rewrite your PageNavi CSS as #content .wp-pagenavi a and override any other less-specific styles.
I know this was a relatively simple example, you could have a lot more advanced CSS rules to differentiate the various links and other elements even more. Hopefully you picked up a few CSS tips along the way too.
Optional WP-PageNavi integration is a pretty cool feature theme developers could integrate in their themes. With the integration method I outlined above, users could easily choose whether or not to use it, and it could be a nice option for a lot of blogs.
Hope you all liked the tutorial, and if you have any requests for future WordPress tutorials or CSS tips, let me know in the comments.
Related posts:
Last weekend I released a free Thematic child theme called Astatic. It was probably the most “advanced” Thematic theme I’ve ever made as I made use of several theme filters, as well as CSS styling to make certain pages look differently using the same HTML markup.
In this tutorial, I’ll go over:
A child theme technically only needs 1 file, a stylesheet named style.css. This differs from a normal theme which requires at least two files, index.php and style.css. Here’s what the header of a very basic child theme’s stylesheet should look like:
/*
Theme Name: Astatic
Theme URI: http://www.themelab.com/free-wordpress-themes/
Description: A very minimal child theme of Thematic
Author: Theme Lab
Author URI: http://www.themelab.com/
Template: thematic
Version: 0.1
*/
Notice the line second from the bottom which says Template: thematic. This is what sets the parent theme to whatever theme is in your /wp-content/themes/thematic/ directory.
You could change this to whatever directory you wanted to inheirit all the parent theme stuff from any other theme, for purposes of this tutorial we’ll stick with Thematic though.
Ever since WordPress 2.7, you can also make pretty much any template file you want in your child theme directory to have it override the parent theme’s template.
Since Thematic has a boatload of action hooks and filters, you probably won’t need to do that. You can make just about any change you want through just a functions.php file in your child theme directory.
You can take advantage of Thematic’s built-in hooks and filters by placing a file called functions.php in your child theme directory.
I used these for removing bits of code from the template without altering the parent theme files. For example, the first part of Astatic’s functions file removes the Javascript code from the head of the document.
It was mostly used for Jquery dropdown menus for navigation. Since I was only planning on having a simple one-level-deep page navigation, I decided to remove it. Here’s the code I used.
function remove_thematic_js() {
remove_action('wp_head','thematic_head_scripts');
}
add_action('init','remove_thematic_js');
Code Explanation
remove_thematic_js because, well, the function is for removing Thematic’s JS.thematic_head_scripts from the wp_head hookTo “override” a function, you first have to remove it, then code a new function to replace it. I did this with the thematic_blogtitle function, so I could wrap h1 tags around it on non-singular pages. First, the removal code:
function remove_thematic_blogtitle() {
remove_action('thematic_header','thematic_blogtitle',3);
}
add_action('init','remove_thematic_blogtitle');
Pretty much identical to the above, except for one seemingly minor detail. Notice the number “3″ in the remove_action line? This is the priority defined in Thematic’s original function files, which needs to match in our function, or it won’t work.
You can find more of these functions in Thematic’s library files. Just make sure the hook name (in this case, thematic_header) and the priority (if applicable) match.
Now, here’s the new and improved blogtitle function:
function new_blogtitle() {
if (is_home() || is_front_page()) { ?>
<h1 id="blog-title"><a href="<?php bloginfo('url') ?>/" title="<?php bloginfo('name') ?>" rel="home"><?php bloginfo('name') ?></a></h1>
<?php } else { ?>
<div id="blog-title"><a href="<?php bloginfo('url') ?>/" title="<?php bloginfo('name') ?>" rel="home"><?php bloginfo('name') ?></a></div>
<?php }
}
add_action('thematic_header','new_blogtitle',3);
Code Explanation
new_blogtitle. Remember, descriptive names.blog-title ID is wrapped in <div> tags rather than <h1>.thematic_header with priority 3 (remember, the same number we used to remove the old blog title function.By default, Thematic displays the full post on the homepage (as opposed to an excerpt). Since I want it to be consistent with all archive and search pages (which have excerpts by default) I needed to change it. Here’s the code I used:
function astatic_content($content) {
if (is_home() || is_front_page()) {
$content= 'excerpt';}
return $content;
}
add_filter('thematic_content', 'astatic_content');
On top of that, I wanted to limit the amount of words in the excerpt to 20.
function new_excerpt_length($length) {
return 20;
}
add_filter('excerpt_length', 'new_excerpt_length');
Credits to WP Engineer for the above code, which could be used on any WordPress theme (not just Thematic).
Of course, you can change the “20″ to whatever you want, just keep in mind you may have to increase the height of the non-singular posts to accommodate more excerpt words, which we’ll go over next.
Now on to my favorite part, the CSS. You’ll notice on any index pages (main index, archives, categories, tags, and search) posts are laid out in two columns. The markup between these and singular pages (single posts and pages) are essentially identical.
I used the .not-singular class to style the index posts differently. This class is output in the <body> tag on any index pages through the body_class function.
I used the following snippet of code to style posts on these index pages.
.not-singular .post {
width: 400px;
height: 150px;
float: left;
margin-right: 50px;
}
Code Explanation
float: left makes the post float to the left, which forms the “columns”.Remember, the body classes change from page to page, depending on what type of page you’re on. Let’s say you’re on a “Pink” category archive page, a body class called category-pink will be made available, and you could set the entire background of the page with the following code: body.category-pink { background-color: pink; }.
Keep in mind, pink background would probably make your visitors want to gauge their eyes out, although hopefully you get the idea of the potential of body_class. You can also take advantage of post_class which functions very similarly for styling various types of posts, also integrated in Thematic.
Since I removed every single page navigation menu through filtering, I decided I would insert a basic page menu through the thematic_abovefooter hook.
function astatic_footernav() {
?>
<ul id="footer-nav">
<li id="home-link"><a href="<?php bloginfo('url'); ?>/"><?php _e('Home', 'thematic'); ?></a></li>
<?php wp_list_pages('title_li=&depth=1') ?>
</ul>
<?php
}
add_action('thematic_abovefooter', 'astatic_footernav', 10);
This is just a basic, one level deep page menu including a translation-friendly “Home” link. Here’s the CSS code to style it:
#footer-nav { clear: both; list-style: none; text-align: center; padding: 50px 0 20px; }
#footer-nav li { border-left: 1px solid #000; display: inline; padding: 0 10px; }
#footer-nav li#home-link { border-left: 0; }
Code Explanation
#footer-nav clears any floats with clear:both, removes the default bullets with list-style:none, aligns the menu to the center, and adds sufficient padding above and below the list.#footer-nav li adds a 1 pixel border (or separator) to the left of every list item, sets them all up on one line, and adds padding to the left and right.#footer-nav li#home-link makes sure no border is displayed to the left of the “Home” link, since that would look slightly odd.I decided to add a footer link back to the Astatic theme page, in case any visitor of an Astatic site was wondering what theme it was using. I used the following code.
function childtheme_theme_link($themelink) {
return $themelink . ' & <a href="http://www.themelab.com/2010/04/03/astatic-free-thematic-child-theme/" title="Astatic Thematic Child Theme">Astatic</a>';
}
add_filter('thematic_theme_link', 'childtheme_theme_link');
Note: Please use & instead of a straight ampersand. I changed it above because it was messing up the code display for some reason.
Basically I’m piggybacking on top of the default “Thematic Theme Framework” link, which can be removed in the Thematic Options page. I picked up this tip from this guide to customizing Thematic.
Make sure to download the Astatic theme and take a peek at the code for a more in-depth look at what went on during the development.
For any more Thematic information, ThemeShaper is the ultimate resource, including their forums. It also may be worth following a site called Thematic 4 You which is run by Thematic lead developer, Chris Gossmann.
I plan on doing even more detailed (if that’s even possible) “theme dissection” tutorials in the Underground when it’s ready. Make sure you sign up to the email list on the previously linked page for any news regarding that, among other goodies.
Phew. I hope you learned a little something hear about making Thematic child themes, and hopefully about child themes in general. Let me know what you think in the comments.
Related posts:
In a lot of WordPress sites’ sidebars, you’ll probably see the monthly archive links make an appearance. These are a list of links that categorize your post by month. If you want to get more specific, you can even group the posts by week or even day. Unless you’re using widgets, these lists are output using the wp_get_archives function. Here are some examples:
<?php wp_get_archives(); ?> – Lists the monthly archives (no parameters needed, it’s monthly by default)<?php wp_get_archives('type=weekly'); ?> – Lists the weekly archives<?php wp_get_archives('type=daily'); ?> – Lists the daily archives<?php wp_get_archives('type=yearly'); ?> – Lists the yearly archivesSo what’s the problem? Well, depending on the site, monthly archive links aren’t very useful to your visitors. I mean, how many times have you visited a site and said “Hmm…I want to check out some posts written in January 2008″?
Probably never, and these links waste valuable space in your sidebar (or footer, whatever) that could be occupied by more useful links.
In this post, we’ll go over how to insert the following into your WordPress theme, including a widget alternative (if available):
There are a few methods to get a link list of popular/useful posts. Here they are:
Sometimes the quantity of comments is a good way to gauge a post’s popularity. If you want to generate a list of links with your most commented posts, here’s the code for that:
First, paste the following function in your functions.php file:
function popularPosts($num) {
global $wpdb;
$posts = $wpdb->get_results("SELECT comment_count, ID, post_title FROM $wpdb->posts ORDER BY comment_count DESC LIMIT 0 , $num");
foreach ($posts as $post) {
setup_postdata($post);
$id = $post->ID;
$title = $post->post_title;
$count = $post->comment_count;
if ($count != 0) {
$popular .= '<li>';
$popular .= '<a href="' . get_permalink($id) . '" title="' . $title . '">' . $title . '</a> ';
$popular .= '</li>';
}
}
return $popular;
}
Then paste the following into your sidebar (or wherever you want a list of popular posts by comments):
<ul>
<?php echo popularPosts(10); ?>
</ul>
You can change the “10″ to however many posts you want. I’m assuming you already have CSS in place in your theme for lists like this, so I won’t go over any CSS styling.
Source: How to List Your Most Popular Posts in WordPress
– This is a relatively new method of generating a list of popular posts. It requires you use the WordPress.com Stats plugin. Here’s the code:
<?php
if (function_exists('stats_get_csv')) {
$top_posts = stats_get_csv ('postviews', 'days=7&limit=8');
if (count($top_posts) > 0) {
echo '<ol>';
foreach ($top_posts as $p) {
?>
<li><a href="<?php echo $p['post_permalink']; ?>"><?php echo $p['post_title']; ?></a></li>
<?php
}
echo '</ol>';
}
}
?>
Remember: You need the WordPress.com stats plugin activated for this code to work. If you just installed it, you should probably leave it on for a few days to collect enough relevant data before using it.
If you want to hide the smiley face added by the plugin, make sure you hide it the right way.
Hint: Change the “ol” tags to “ul” if you want an unordered list instead of a numbered list.
Source: Quick and Easy Popular Posts for Your WordPress Blog
Using WordPress’ built-in blogroll functionality, you can manually select a link to whichever posts you want. This is probably the most flexible way since you have the most control over how your links are displayed, and they don’t even have to be on your site.
You can also categorize your links and list them all in separate lists, using just one line of code with the built-in wp_list_bookmarks function.
<?php wp_list_bookmarks('title_before=<h3>&title_after=</h3>&category_before=&category_after='); ?>
This will output all your blogroll list categories with “h3″ titles. Depending on your sidebar’s markup, you may want to add code to be displayed before and after each list.
If you want to exclude any categories, you can use the exclude_category parameter with a comma-separated list of link category IDs.
If you don’t know how to use the blogroll feature, I found this pretty nice screencast on WordPress.tv (try watching it in full screen mode).
This is something pretty simple that I’ve gone over before. Using the same wp_get_archives function we went over above, you can modify to get a list of recent posts.
<?php wp_get_archives('title_li=&type=postbypost&limit=10'); ?>
The type=postbypost is the type to use. If you have a ton of posts, I’d recommend using a limit so all of your posts don’t show up.
You can also use the “Recent Posts” widget, assuming your sidebar is widgetized.
I know on some sites, monthly archive links can be useful, like perhaps on a news site, or an “of the day” site (like for cartoons or recipes).
Some people glance at them just to see how long the blog has been active, it can help credibility (hint: add the show_post_count=1 parameter to show a post count next to monthly archive links).
Most of the time, however, it’s a waste of space. It can be replaced with some other much more useful links, like popular content or related posts that users would find more value in.
Any monthly archive links could be placed on a site map page and out of your sidebar.
In the comments, I’d be interested to hear your feedback. Do you use monthly archive links? When do you think they could be relevant? Do you have any other useful alternative examples?
Related posts:
One way to increase visitor engagements is to reward their comments by showcasing them on your website. Additionally, you can also feature the top commenters as well, linking back to their website in the process. Here we’ll create a dedicated Page Template to display those comments and commenters in one place.
In short, this tutorial will teach you how to:
The easiest way to create a Page Template is to open the page.php file in your theme, which will roughly look like this:
<?php get_header(); ?>
<div id="content">
<?php if (have_posts()) : while (have_posts()) : the_post(); ?>
<div class="post" id="post-<?php the_ID(); ?>">
<h2 class="page_title"><?php the_title(); ?></h2>
<?php the_content(); ?>
</div>
<?php comments_template(); ?>
<?php endwhile; endif; ?>
</div>
<?php get_sidebar(); ?>
<?php get_footer(); ?>
Copy and paste page.php’s content and add this to the very top:
<?php /* Template Name: Comments Central */ ?>
And save it. There’s no real rules on naming a Page Template file, but it’s a good idea to go with a prefix to make it recognizable, say “pt-comment-central.php”. We haven’t added anything into this Page Template, but it’s up and running and selectable on the write new Page dashboard area.
For this Page Template, we’ll feature four different aspects of comments:
First, we’ll do Recent Comments:
<h3>Recent Comments</h3>
<ul id="cc-recent-comments">
<?php
$max = 7; // number item to get
global $wpdb;
$sql = "SELECT c.*, p.post_title FROM $wpdb->comments c INNER JOIN $wpdb->posts p ON (c.comment_post_id=p.ID) WHERE comment_approved = '1' AND comment_type not in ('trackback','pingback') ORDER BY comment_date DESC LIMIT $max";
$results = $wpdb->get_results($sql);
$template = '%g <a href="%au">%an</a> on <a href="%pu#comment-%cid">%pt</a>';
$echoed = 0;
foreach ($results as $row) {
$tags = array('%ct','%cd','%g','%pt','%pu','%au','%an','%cid');
$replacements = array($row->comment_title,$row->comment_date,get_avatar($row->comment_author_email,'32'),$row->post_title,get_permalink($row->comment_post_ID),$row->comment_author_url,$row->comment_author,$row->comment_ID);
echo '<li>' . str_replace($tags,$replacements,$template) . '</li>';
$echoed = 1;
}
if ($echoed==0)
echo '<li>No comment found.</li>';
?>
</ul>
The SQL query asks for all approved comments sorted by date (latest first). $max is where we set the amount of comments to get, 7 in our case. The output of the code above will be an unordered list of recent comments:

With a little CSS we can straighten that to look better:
#cc-recent-comments li {
width: 100%;
float: left;
list-style-type: none;
}
#cc-recent-comments li img {
float: left;
margin-top: -5px;
}

$template determines how the actual text will be written; this is based on the format made by WP Comment Remix, and you can follow that link to learn more on customizing it (look for ‘tokens’).
Next is Recent Pingbacks / Trackbacks:
<h3>Recent Pingbacks / Trackbacks </h3>
<ul id="cc-recent-trackbacks">
<?php
$sql = "SELECT c.*, p.post_title FROM $wpdb->comments c INNER JOIN $wpdb->posts p ON (c.comment_post_id=p.ID) WHERE comment_approved = '1' AND comment_type not in ('trackback','pingback') ORDER BY comment_date DESC LIMIT $max";
$results = $wpdb->get_results($sql);
$template = '%g <a href="%au">%an</a> on <a href="%pu#comment-%cid">%pt</a>';
$echoed = 0;
foreach ($results as $row) {
$tags = array('%ct','%cd','%g','%pt','%pu','%au','%an','%cid');
$replacements = array($row->comment_title,$row->comment_date,get_avatar($row->comment_author_email,'32'),$row->post_title,get_permalink($row->comment_post_ID),$row->comment_author_url,$row->comment_author,$row->comment_ID);
echo '<li>' . str_replace($tags,$replacements,$template) . '</li>';
$echoed=1;
}
if ($echoed==0)
echo '<li>No comment found.</li>';
?>
</ul>
The code above is very similar to the one we have for Recent Comments, the only differences being that we’re now asking for comments with ‘comment_type’ under ‘pingback’ / ‘trackback’, and the template is a bit different as well. Result:

Here’s the code for Top Commenters:
<h3>Top Commenters</h3>
<ul id="cc-top-commenters">
<?php
$sql = "SELECT comment_author, comment_author_url, comment_author_email, count(comment_ID) as comment_count FROM $wpdb->comments WHERE comment_approved = '1' AND comment_type not in ('trackback','pingback') GROUP BY comment_author, comment_author_url, comment_author_email ORDER BY comment_count DESC LIMIT $max";
$results = $wpdb->get_results($sql);
$template = '<a href="%au">%g %an</a> (%c comments)';
$echoed = 0;
foreach ($results as $row) {
$tags = array('%g','%au','%an','%c');
$replacements = array(get_avatar($row->comment_author_email,'32'),$row->comment_author_url,$row->comment_author,$row->comment_count);
echo '<li>' . str_replace($tags,$replacements,$template) . '</li>';
$echoed = 1;
}
if ($echoed==0)
echo '<li>No commenter found.</li>';
?>
</ul>
Nothing too mind-blowing there. Do notice the cool get_avatar() function, though, which will give you the Gravatar for anyone whose email address you specify. In this case, we fetch the avatar image using the commenter’s e-mail address. With the CSS similar to the one we have for recent comments, we can have this result:
#cc-top-commenters li {
width: 100%;
float: left;
list-style-type: none;
}
#cc-top-commenters li img {
float: left;
margin-top: -5px;
}

Last is Most Commented Posts:
<h3>Most Commented Posts</h3>
<ul id="cc-most-comments">
$sql = "SELECT p.*, c.comment_count FROM $wpdb->posts p INNER JOIN (SELECT comment_post_id, count(comment_ID) as comment_count from $wpdb->comments WHERE comment_approved='1' GROUP BY comment_post_id) c ON (c.comment_post_id=p.ID) ORDER BY c.comment_count DESC LIMIT $max";
$results = $wpdb->get_results($sql);
$template = '<a href="%pu">%pt</a> (%c comments)';
$echoed = 0;
foreach ($results as $row) {
$tags = array('%pd','%pt','%pu','%c');
$replacements = array($row->post_date,$row->post_title,get_permalink($row->ID),$row->comment_count);
echo '<li>' . str_replace($tags,$replacements,$template) . '</li>';
$echoed = 1;
}
if ($echoed==0)
echo '<li>No commenter found.</li>';
?>
</ul>

And that’s it. Next, we’ll add some extra coolness by adding some stuff that only the admin can see.
To show stuff only for the admins, we can use this code snippet from WPCandy:
<?php
global $user_ID;
if( $user_ID ) :
if( current_user_can('level_10') ) :
// admin-only stuff here.
endif;
endif; ?>
Now on the Dashboard, we get a quick glance of a site’s total, approved, pending review and spam comments. Let’s replicate this for our Page Template for easier, admin-only access:
<?php
$num_comm = wp_count_comments();
?>
Total Comments: <a href="<?php bloginfo('wpurl'); ?>/wp-admin/edit-comments.php?"><?php echo $num_comm->total_comments; ?></a>
Approved: <a href="<?php bloginfo('wpurl'); ?>/wp-admin/edit-comments.php?comment_status=approved"><?php echo $num_comm->approved; ?></a>
Moderated: <a href="<?php bloginfo('wpurl'); ?>/wp-admin/edit-comments.php?comment_status=moderated"><?php echo $num_comm->moderated; ?></a>
Spam: <a href="<?php bloginfo('wpurl'); ?>/wp-admin/edit-comments.php?comment_status=spam"><?php echo $num_comm->spam; ?> </a>

wp_count_comments() is a neat function that returns an array of various comment stat numbers. We’re adding links to the respective comment administration area too.
Last, say you find a cool comment-related plugins you want to incorporate into this Page Template. Instead of adding more codes, let’s just add support for it. For this example, I’ll go with Activity Sparks plugin, which can “display a ’sparkline’ style graph in your sidebar indicate post and/or comment activity. ” Sounds great to me.
Usually, a plugin’s readme.txt file will teach you how to add it into your theme files. In our case, the code can be like this:
<?php
if(function_exists('activitysparks')) {
activitysparks(array('dataset'=>'legend','height_px'=>100,'width_px'=>600,'period'=>30, 'ticks'=>24));
}
?>

function_exists() checks whether a particular function is available; in our case, the activitysparks function, which will be available if the plugin has been uploaded and activated. If it’s there, we show the graph. If not, then our Page Template won’t show anything (but it will still run just fine, no errors).
An example of this Page Template is available here. It uses the codes you see here with a few modifications, mostly to keep the HTML structure consistent with the rest of the website. The whole code for that Page Template is available at Pastebin.
$template we use to format the output can be learned more from that page, too.
Related posts: