NOTICE: This development is now part of K2 and have been moved to K2. You can get the latest code from K2 SVN.
For those that been wondering how my commenting system is submitting comment without reloading the whole page, the answer is AJAX commenting. Please take note that it’s not a WordPress 2.0 feature (up until now I guess). WordPress theme like K2 and Squible already bundle this feature into their theme.
There’s 2 ways that you can implement AJAX commenting into your WordPress theme, either you download K2 or Squible or hack your current theme so that it can support this awesome feature. Porting this hack is easy like sticking fish into a pond even without knowing any PHP knowledge and the only thing important is that you know the basic function of WordPress templating system.
Can’t really confirm the actual hack written by whom, but listed below is the known individuals that I learn from on how to port AJAX commenting system into any WordPress theme:
How to implement AJAX Commenting in your current WordPress theme
Quick note that this method is tested on WordPress Default theme (Kubrick).
- Backup your current theme.
- Download ajax-comment.zip (modified version from K2) zipped file. There are 1 important file and 3 JavaScript to be downloaded. For this tutorial, I’m using scriptalious 1.5.0 final library. As explain by Nico from siriux.net,
comments-ajax.php handles the AJAX requests and acts just like wp-comments-post.php from WordPress. ajax_comments.js is the JavaScript part that sends AJAX requests and updates the page. You have to adjust this file to match your style ids! And the comments ol tag must be present for this to work, even if it’s empty.
prototype.js is a JavaScript framework that aims to ease development of dynamic web applications. effect.js handles all the effects.
- Place the comments-ajax.php file inside your current WordPress theme directory. For example /wp-content/themes/your_theme/
- Create a new folder named js inside your WordPress theme folder. For example /wp-content/themes/your_theme/js/
- Place the 3 javascript, ajax_comments.js, prototype.js.php and effect.js.php library into the js folder.
- Open header.php, somewhere before <?php wp_head(); ?>, insert this code
<?php if (is_single() and ('open' == $post-> comment_status) or ('comment' == $post-> comment_type) ) { ?> <script type="text/javascript" src="<?php bloginfo('template_directory'); ?>/js/prototype.js.php"></script> <script type="text/javascript" src="<?php bloginfo('template_directory'); ?>/js/effects.js.php"></script> <script type="text/javascript" src="<?php bloginfo('template_directory'); ?>/js/ajax_comments.js"></script> <?php } ?> - Open comments.php, find
<ol class="commentlist">and replace that line with<ol class="commentlist" id="commentlist">. Notice that we add an additional id=”commentlist”.Take note that most of WordPress theme that I tried or those themes that made for public download, uses ordered list with class commentlist for displaying submitted comments. So there’s 99% posibility that your theme is one of theme using the same tag with the same class.
- This should be tricky. In the same file, find
<?php if ($comments) : ?>. Make sure that<?php if ($comments) : ?>is below<ol class="commentlist" id="commentlist">at any cause. Example,<ol class="commentlist" id="commentlist"> <?php if ($comments) { ?>In a normal WordPress theme,
<?php if ($comments) { ?>is on top of<ol class="commentlist">.As a result, this won’t work and the submitted comment will not be display and load in real time viewing.
Therefore,
<ol class="commentlist" id="commentlist">must always be on top of<?php if ($comments) { ?>. - Somewhere before the Reply Form find,
<?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. --> <?php else : // comments are closed ?> <!-- If comments are closed. --> <p class="nocomments">Comments are closed.</p> <?php endif; ?>Take note that this line of code may be different from your current theme. This is because some of WordPress public released theme does not include some of the if else statement for no comment and comment closed. Replace those lines with
<?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. --> <li id="hidelist" style="display:none"></li> </ol> <p id="nocomment">No comments yet</p> <?php else : // comments are closed ?> <!-- If comments are closed. --> <li style="display:none"></li> </ol> <p>Comments are closed.</p> <?php endif; ?>Notice the additional <ol> end tag and hidden <li> tag.
- In comments.php, find
<?php if ('open' == $post->comment_status) : ?>. Before OR after that line, put this code<div id="loading" style="display: none;">Posting your comment.</div> <div id="errors"></div>The first line will indicate that the comment is currently in posting state and the second line is use to indicate any sorts of error like an empty required field. Probably I will include on how to customize both of this message to suit your current theme. Take note that the id’s must matched the one in your ajax_comments.js.
- In comments.php, find and replace
<form action="<?php echo get_option('siteurl'); ?>/wp-comments-post.php" method="post" id="commentform">to
<form id="commentform" action="<?php echo get_option('siteurl'); ?>/wp-comments-post.php" method="post" onsubmit="new Ajax.Updater({success: 'commentlist'}, '<?php bloginfo('stylesheet_directory') ?>/comments-ajax.php', {asynchronous: true, evalScripts: true, insertion: Insertion.Bottom, onComplete: function(request){complete(request)}, onFailure: function(request){failure(request)}, onLoading: function(request){loading()}, parameters: Form.serialize(this)}); return false;">This code is borrowed from K2 theme and should be in one line. With this line of code, it’s possible even your browser JavaScript is disable, the comment will still be send using the normal comment post. As a result, your visitor will have an option between AJAX commenting or normal comment post.
- This is optional. Finally check whether your input submit button have or uses
id="submit".If not, please insert
id="submit"into that line. Example,<input name="submit" type="submit" id=”submit” value=”Submit” />Some WordPress theme replace that value with their own id and some of theme doesn’t even have that id. For example theme Blix does not use
id="submit"in their input tag. Theid="submit"must be included so that the AJAX commenting will work perfectly. - Save and close all file.
- Make sure that the JavaScripts files are loaded when viewing single entry posting. Test and see whether it works.
Additional note
- AJAX commenting will not work if the comment is inside definition list. An example theme that using definition list is Regulus from Binary Moon.
- In order to make the comment numbering increment properly, you need to remove <?php $count++; ?> and uses the standard ordered list.
-
Your comments.php won’t be a valid XHTML unless you put a hidden nested list inside the ordered list, example
<li style="display:none">No Comments</li>.But as a result, the first comment will be count as 2 but will change to 1 if the page is reloaded again. If you don’t care about XHTML validation, then you should probably ignore the empty ordered list. This is because we change the placing of
<ol class="commentlist" id="commentlist">on top of<?php if ($comments) { ?>.UPDATE: Refer to step 9 and download ajax_comments.js revision 2.4.
- An older prototype and script.alicio.us library is available if you don’t want to use the final release. The file size are a bit smaller. Take note that this file is originally taken from K2 file and the script does not cover in this tutorial.
- For those that having problem copy pasting the codes, please view or download the ajax commenting addon codes in txt format.
nocomment,hidelist,errorsandloadingare the element id’s assigned uniquely to ajax comment. You should not use any of these id’s in your theme or your stylesheet to avoid conflict with ajax commenting.- To hide the comment edit link from visible to user that is not logged in, find
<?php edit_comment_link('e','',''); ?>and replace with
<?php if ( $user_ID ) { ?><?php edit_comment_link('e','',''); ?><?php } ?> -
Currently doesn’t work properly if Spam Karma is enabledThanks to tinyau, now compatible with Spam Karma 2 and WordPress 2.0 (update to revision 2.4). Can’t confirm with other kind of spam filter plugins since I don’t use any.Spam Karma 2 compatibility code changes:
comments-ajax.php, line 61 change from
wp_new_comment($commentdata);to
$new_comment_ID = wp_new_comment($commentdata);comments-ajax.php, line 72 change from
$comment = $wpdb->get_row("SELECT * FROM {$wpdb->comments} WHERE comment_ID = {$wpdb->insert_id};");to
$comment = $wpdb->get_row("SELECT * FROM {$wpdb->comments} WHERE comment_ID = " . $new_comment_ID); - There seems to be a bit of confusion here. I didn’t say that you MUST use ol tag(ordered list). You can use either unordered list or ordered list. As long as it’s a nested list. There’s also a way to make this work inside only a
divbut that’s a different story to tell.
You are free to view this page source code for clearer view. But certain part of the code placing has been heavily modified. But I hope you still get the idea.
Additional Bonus
Below are some random selected themes with only the changes files.
- Download an example of WordPress Default Theme (Kubrick) with AJAX commenting (changes file only).
- ..more upon request.
Changelog
22-January-2005
- Apply tinyau Spam Karma 2 compatibility fix in revision 2.4 to comments-ajax.php.
- Fix code formatting error.
20-January-2005
- Major update to core file. You are advise to re-download all the ajax-comment.zip revision 2.3 file.
- Modified the condition statement to call all the script in header.php. Will not be call if comment type is trackback or close.
- Change the core file extension. This affect step 6 code changes in header.php.
29-December-2005
- As pointed by tinyau, I added user cookie information to comments-ajax.php rev 2.2 line 63 (taken from wp-comments-post.php).
if ( !$user_ID ) : setcookie('comment_author_' . COOKIEHASH, stripslashes($comment_author), time() + 30000000, COOKIEPATH, COOKIE_DOMAIN); setcookie('comment_author_email_' . COOKIEHASH, stripslashes($comment_author_email), time() + 30000000, COOKIEPATH, COOKIE_DOMAIN); setcookie('comment_author_url_' . COOKIEHASH, stripslashes($comment_author_url), time() + 30000000, COOKIEPATH, COOKIE_DOMAIN); endif; - Regarding
echo "<li style=\"display:none\"".$matches[1].”>”.$matches[2].”</li>”;an explaination to Christoph. You can remove style=\”display:none\” but not".$matches[1].”. This is because".$matches[1].”determine your first comment nested list styling and duplicate the style to the comment.This is known to be bugged if you are using alt background color. But it’s still being determined by your theme whether the comment list using any style or not.
Unfortunately, according to effects.js,
Effect.Appearwill not appear according to it’s effect properly ifdisplay:noneis removed (effects.js line 543).
27-December-2005
- Step 9 is updated again, added 1 missing code line.
- Updated the example file of WordPress Default Theme (Kubrick) with AJAX commenting revision 2.2.
- Updated the ajax-comment.zip zipped file with the new ajax_comments.js revision 2.4.
- Now it’s possible to hide error notice if comment is successfully submitted.
- Added few more pointers to Additional Notes and the tutorial.
26-December-2005
- Comment box and submit buttons are disabled to avoid spamming if the comment is successfully added.
- Comment numbering is now increment properly even if no submitted comment yet (Not working with IE).
- Changes are made to step 9 which include using the actual Kubrick code as example, additional id’s (
hidelistandnocomment) and rearranging the ol tag.
Plugin compatibility
Below are some comment related plugin known to be compatible with AJAX commenting
- LiveCommentPreview by Jeff Minard and Iacovos Constantinou. You have to put extra line of code inside
function commentAddedline 4 ajax_comments.js to hide the preview comment on submit.Before
Element.hide('errors');addElement.hide('commentPreview');. - Quote Comment by Viper007Bond. For nested quote fix, please download Quote Comment V2.0.
Updated files
- ajax-comment.zip revision 2.4 (22-1-2006).
- WordPress Default Theme (Kubrick) with AJAX commenting revision 2.4 (22-1-2006).
- ajax_comments.js revision 2.4 (20-1-2006).
Licensed under the Creative Commons Attribution 2.5 License
Last updated Jan 22th, 2006 at 13:57 pm