A Path Less Taken

Breaking with convention in a very conventional fashion. Powered by WordPress

"What would you attempt to do if you knew you could not fail?"
Dr. Robert Schuller

Saturday, July 11, 2009

Category: Web Design Author: JJ 5 Comments

Comments, comments, comments. What blog is really complete without comments? One of the hallmarks of a unique WordPress theme is the way it handles comments. That’s why we are diving into this important topic. As usual my timing is either awesome or terrible, but I honestly can’t tell. With the recent release of WordPress 2.7 there was a significant overhaul of the comments system. Threaded (nested) comments were included which is a major step forward. Also, the comments loop was notably improved. For more details in the words of the WordPress team you can check here.

To start with, we need to get our comments to appear at the right point in our theme using the right comments template. Since I’m planning my theme for WordPress 2.7 and higher, I’m going to have the “default” theme take care of older and less cool comments. To do this I have to add the following block of code to my index.php file right below the closing DIV tag of my postFooter.

1
2
3
4
5
6
7
8
/* If Wordpress version 2.7 or higher then utilize the custom comments display template. */
if (!function_exists ('wp_list_comments')) {
	comments_template ('../welcome/comments.php', true) ;
}
/* If Wordpress version 2.6 or lower then utilize the default comments display template. */
else {
	comments_template () ; // Get wp-comments.php template
}

The documentation suggests that you can check for the function wp_list_comments. In my case I’m checking that it does NOT exist. I know. This makes no sense to me either. For some reason that I have yet to figure out the PHP function function_exists is returning false indicating that wp_list_comments does not exist when it obviously does. It could be an issue of it not existing at that point in the execution of the script, but what do I know. Please post a note to help me out if you know what I’m doing wrong. Basically all this block of code is doing is using the Welcome theme’s comments.php file when the function is NOT found and the default theme’s comments.php otherwise. It’s backwards, but it works for me so let’s roll with it.

Next I created my own comments.php in the Welcome theme folder and saved the empty file. Then I previewed the theme and looked at a post with comments. No comments were displayed which told me it was using my empty file. Then I went in and “basically” copied the WordPress 2.8.1 default theme comments.php files’ contents into my comments.php file. I modified the layout of the file heavily to suit my formatting tastes and added in a number of comments that were helpful to me. I changed the TEXTAREA of the cols property from 100% to 60% because our theme has right hand navigation. Below is the code without my comments. The comments will be included in the finished Welcome theme.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
<?php
	if (!empty($_SERVER['SCRIPT_FILENAME']) && 'comments.php' == basename($_SERVER['SCRIPT_FILENAME']))
		die ('Please do not load this page directly. Thanks!');
 
	if ( post_password_required() ) { ?>
		<p class="nocomments">This post is password protected. Enter the password to view comments.</p>
	<?php
		return;
	}
?>
 
<!-- You can start editing here. -->
 
<?php
	if (have_comments ()) {
?>
		<h3 id="comments"><?php comments_number('No Comments', 'One Comment', '% Comments' );?> to &#8220;<?php the_title(); ?>&#8221;</h3>
		<!-- The Wordpress Comments Loop (displaying comments) -->
		<ul id="commentlist">
		<?php wp_list_comments () ; ?>
		</ul>
		<div id="commentnav"><?php paginate_comments_links () ; ?></div><!-- close commentnav -->
<?php
	}
	else {
		if (comments_open ()) {
			print "<div id=\"nocomments\">No comments found.  Please enter a comment if you have a question or contribution.</div><!-- close nocomments -->" ;
		}
		else {
			print "<div id=\"nocomments\">Comments are closed.</div><!-- close nocomments -->" ;
		}
	}
	if (comments_open ()) {
?>
		<div id="respond">
		<h3><?php comment_form_title( 'Leave a Reply', 'Leave a Reply to %s' ); ?></h3>
		<div class="cancel-comment-reply">
			<small><?php cancel_comment_reply_link(); ?></small>
		</div>
<?php	
		if (get_option('comment_registration') && !is_user_logged_in()) {
?>
			<p>You must be <a href="<?php echo wp_login_url(get_permalink()); ?>">logged in</a> to post a comment.</p>
<?php
		}
		else {
?>
			<form action="<?php echo get_option('siteurl'); ?>/wp-comments-post.php" method="post" id="commentform">
<?php
			if (is_user_logged_in()) {
?>
				<p>Logged in as <a href="<?php echo get_option('siteurl'); ?>/wp-admin/profile.php"><?php echo $user_identity; ?></a>. <a href="<?php echo wp_logout_url(get_permalink()); ?>" title="Log out of this account">Log out &raquo;</a></p>
<?php
			}
			else {
?>
				<p><input type="text" name="author" id="author" value="<?php echo esc_attr($comment_author); ?>" size="22" tabindex="1" <?php if ($req) echo "aria-required='true'"; ?> />
				<label for="author"><small>Name <?php if ($req) echo "(required)"; ?></small></label></p>
 
				<p><input type="text" name="email" id="email" value="<?php echo esc_attr($comment_author_email); ?>" size="22" tabindex="2" <?php if ($req) echo "aria-required='true'"; ?> />
				<label for="email"><small>Mail (will not be published) <?php if ($req) echo "(required)"; ?></small></label></p>
 
				<p><input type="text" name="url" id="url" value="<?php echo esc_attr($comment_author_url); ?>" size="22" tabindex="3" />
				<label for="url"><small>Website</small></label></p>
<?php
			}
?>
			<!--<p><small><strong>XHTML:</strong> You can use these tags: <code><?php echo allowed_tags(); ?></code></small></p>-->
 
			<p><textarea name="comment" id="comment" cols="60%" rows="10" tabindex="4"></textarea></p>
 
			<p><input name="submit" type="submit" id="submit" tabindex="5" value="Submit Comment" />
			<?php comment_id_fields(); ?>
			</p>
			<?php do_action('comment_form', $post->ID); ?>
 
			</form>
<?php
		}
		print "</div><!-- close respond -->" ;
	}
?>

There looks like a lot of stuff happening here, but it’s really pretty straight forward once you understand what’s happening. Let’s look at a few key functions.

  • wp_list_comments () – This function is the comments loop. It outputs all the comments, postbacks and tracebacks including the new reply or nested comments. It is sensitive to the paging properties set in your WordPress implementation. It is the super loop. What’s more, this cool function outputs all the comments and nested comments with new default CSS classes that let us go nuts formatting them anyway we like. I will go into this in more detail when we style our theme. I know that the excitement is building. The truth is I’ve been styling as I go, but I don’t want to show it to you until it’s slightly better than hideous. Don’t worry, you’ll see!
  • paginate_comments_links () – This function works in conjunction with wp_list_comments () to make sure your previous and next links are always in sync with your comment paging. I’m pretty sure paging is a new feature of 2.7.
  • comments_open () – Checks to see if comments are still open for the post being displayed. This is used to make decisions about content to display. For instance the comment form is only displayed if this function returns true.

There are a few important things to take note of. The section at the top is straight from the documentation and should be included in any theme you build as is. It prevents the bad internet people from hacking your site through your comments. Also, I went into WordPress administration and activated the Settings >> Discussions >> Enable threaded (nested) comments 5 levels deep option. This allowed the Reply link to show up in my comment posts. Then I added a reply to test that it was working correctly. I found that Akismet, a great link spam blocking tool for WordPress, identified my comment reply as Spam. That was kind of funny since I was logged into the blog as the admin when I made the post. It’s the kind of thing that happens to me all the time. Thirty minutes later I found the problem, approved the comment as not spam and was able to successfully view the comment reply.

Also, note that I made VERY minor changes to comments.php. If the default functionality suits your needs then you may want to go with that and just use CSS styles to format the results. It’s all up to you as the theme author.

In the next post we will figure out how to build our own custom Page Not Found (404) response. This is another great opportunity to make our theme look polished and complete with very little effort on our part.

5 Comments to “Building WordPress Themes – Part 9”

Leave a Reply

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="" highlight="">