Home > WordPress > 为主题添加AJAX提交评论功能
2009November . 6th

为主题添加AJAX提交评论功能

本文参考了Xiaorsz的使用 jQuery 实现 wordpress 的 Ajax 留言
前几天,为了提高评论体验,为了减轻服务器负担,我为主题添加了AJAX提交评论功能,现在分享一下方法。
首先需要在主题的function.php文件里添加一段函数:

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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
< ?php
function fail($s) {
    header('HTTP/1.0 500 Internal Server Error');
    echo $s;
    exit;
}
 
function ajax_comment(){
 
if($_POST['action'] == 'ajax_comment') {
 
    global $wpdb, $db_check;
        // Check DB
        if(!$wpdb->dbh) {
            echo('Our database has issues. Try again later.');
			die();
        } 
nocache_headers();
$comment_post_ID = (int) $_POST['comment_post_ID'];
 
$status = $wpdb->get_row("SELECT post_status, comment_status FROM $wpdb->posts WHERE ID = '$comment_post_ID'");
if ( empty($status->comment_status) ) {
    do_action('comment_id_not_found', $comment_post_ID);
    fail('The post you are trying to comment on does not currently exist in the database.');
} elseif ( 'closed' ==  $status->comment_status ) {
    do_action('comment_closed', $comment_post_ID);
    fail('Sorry, comments are closed for this item.');
} elseif ( in_array($status->post_status, array('draft', 'pending') ) ) {
    do_action('comment_on_draft', $comment_post_ID);
    fail('The post you are trying to comment on has not been published.');
}
$comment_author       = trim(strip_tags($_POST['author']));
$comment_author_email = trim($_POST['email']);
$comment_author_url   = trim($_POST['url']);
$comment_content      = trim($_POST['comment']);
// If the user is logged in
$user = wp_get_current_user();
if ( $user->ID ) {
    $comment_author       = $wpdb->escape($user->display_name);
    $comment_author_email = $wpdb->escape($user->user_email);
    $comment_author_url   = $wpdb->escape($user->user_url);
    if ( current_user_can('unfiltered_html') ) {
        if ( wp_create_nonce('unfiltered-html-comment_' . $comment_post_ID) != $_POST['_wp_unfiltered_html_comment'] ) {
            kses_remove_filters(); // start with a clean slate
            kses_init_filters(); // set up the filters
        }
    }
} else {
    if ( get_option('comment_registration') )
        fail('Sorry, you must be logged in to post a comment.');
}
$comment_type = '';
if ( get_option('require_name_email') && !$user->ID ) {
    if ( 6> strlen($comment_author_email) || '' == $comment_author )
        fail('Sorry: please fill the required fields (name, email).');
    elseif ( !is_email($comment_author_email))
        fail('Sorry: please enter a valid email address.');
}
if ( '' == $comment_content )
    fail('Sorry: please type a comment.');
// Simple duplicate check
$dupe = "SELECT comment_ID FROM $wpdb->comments WHERE comment_post_ID = '$comment_post_ID' AND ( comment_author = '$comment_author' ";
if ( $comment_author_email ) $dupe .= "OR comment_author_email = '$comment_author_email' ";
$dupe .= ") AND comment_content = '$comment_content' LIMIT 1";
if ( $wpdb->get_var($dupe) ) {
    fail('Duplicate comment detected; it looks as though you\'ve already said that!');
}
$commentdata = compact('comment_post_ID', 'comment_author', 'comment_author_email', 'comment_author_url', 'comment_content', 'comment_type', 'user_ID');
if( !$user->ID ){
	$result_set = $wpdb->get_results("SELECT display_name, user_email FROM $wpdb->users WHERE display_name = '" . $comment_author . "' OR user_email = '" . $comment_author_email . "'");
	if ($result_set) {
	if ($result_set[0]->display_name == $comment_author){
	fail( __('Error: you are not allowed to use the nickname that you entered.if you are the administrator you hava to login to comment.','philna2') );
	} else {
	fail( __('Error: you are not allowed to use the email that you entered.if you are the administrator you hava to login to comment.','philna2') );
	}
	}
}
$comment_id = wp_new_comment( $commentdata );
$comment = get_comment($comment_id);
 
if( !$user->ID ){
	setcookie('comment_author_' . COOKIEHASH, $comment->comment_author, time() + 30000000, COOKIEPATH, COOKIE_DOMAIN);
	setcookie('comment_author_email_' . COOKIEHASH, $comment->comment_author_email, time() + 30000000, COOKIEPATH, COOKIE_DOMAIN);
	setcookie('comment_author_url_' . COOKIEHASH, clean_url($comment->comment_author_url), time() + 30000000, COOKIEPATH, COOKIE_DOMAIN);
}
@header('Content-type: ' . get_option('html_type') . '; charset=' . get_option('blog_charset'));
?>
	//这里需要粘贴你的评论框架代码,不过相关的调用代码有所变化:
	//评论ID:$comment->comment_ID
	//评论者名字:$comment->comment_author
	//判断评论者是否填写了网站地址:$comment->get_comment_author_url
	//评论者URL:$comment->comment_author_url
	//评论时间:mysql2date(__('F jS, Y'),$comment->comment_date)
	//评论者e-mail:$comment->comment_author_email
	//评论内容$comment->comment_content
< ?php
	die();
}
}
add_action('init', 'ajax_comment');
//添加AJAX评论钩子
?>


如果处理评论内容里的换行符的话,$comment->comment_content需做以下处理:

1
2
3
4
5
< ?php
$aj_order   = array("\r\n", "\n", "\r");
$aj_comment_content = str_replace($aj_order,'<br>',$comment->comment_content);
echo $aj_comment_content;
?>

用jQuery写提交评论时的脚本,这也是关键的部分:

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
jQuery(document).ready(function() {    
if (jQuery('#commentform').length) {
    jQuery('#commentform').submit(function(){    //ID为 commentform 的表单提交时发生的函数,也就是整个留言输入框 form 的ID。
		var ajaxCommentsURL = window.location.href;
        jQuery.ajax({
            url: ajaxCommentsURL,
            data: jQuery('#commentform').serialize()+'&action=ajax_comment',    
            type: 'POST',
            beforeSend: function() {
            jQuery('#commenterror').hide();
            var submit='<div id="commentload" style="display: none;background: url("img/spinner.gif") no-repeat scroll 0 50%;margin: 0 auto;">Submitting Comment...</div>';    //创建名为 submit 的字符串,稍后插入,这里的样式大家自己根据需要定义,那个背景图片自己去下哈。
	     var error='<div id="commenterror" style="display: none;margin: 0 auto;">Posted comment fail.</div>';    //创建名为 error 的字符串
	        jQuery('#comments').after(submit);    // 在ID为 comments 的元素后插入刚定义的 submit
	        jQuery('#comments').after(error);    // 同样插入刚定义的 error
                jQuery('#commentload').slideDown();  // 让submit 向下滑出
            },
            error: function(request) {    //发生错误时
                jQuery('#commentload').hide();    //隐藏  submit
                jQuery('#commenterror').show("slow").html(request.responseText); //显示 error 
            },
            success: function(data) {
                jQuery('textarea').each(function(){
                    this.value='';
                });
                jQuery('#commenterror').hide().html();
                if (!jQuery('#thecomments').length) {
                jQuery('#pinglist').before('<ol id="thecomments"></ol>');}
                jQuery('#thecomments').append(data);    //向ID为 thecomments 的元素添加数据,也就是整个 ol 或 ul
				var new_comment = jQuery('#thecomments li:last').hide();    //让最新添加的数据隐藏
				new_comment.slideDown(1000);    //再显示,这里是为了实现滑出的效果,不想要也可以直接显示
                jQuery('#commentform:input').attr('disabled', true);
                jQuery('#commentload').slideUp("slow");
		jQuery('#messagebox').slideUp("slow");    //这是针对我模版而加的,因为我模版在没有留言时会有个 nocomment 的元素,我要让添加一条留言后他自动隐藏,要不然会矛盾,呵呵,这个可以自行选择要或不要
		setTimeout(function() {
                jQuery('#commentform:input').removeAttr('disabled');
                }, 10000);        //这里是设置10秒之后才可以再次留言,自行设置,单位毫秒。
            }
        });
       return false;
   } );
}})
注意:

脚本里的对象ID要对应主题里的评论相关框架的ID。

后续步骤:

为commentload,commenterror写CSS。

有待完善的地方:

AJAX提交后的评论序号显示为1。

  1. 2009November . 6th - 1:24 PM

    是什么样的效果呢 :grin:

  2. 2009November . 6th - 1:24 PM

    看到了,很酷 :grin:

  3. 2009November . 6th - 1:39 PM

    我来试验试验

  4. 2009November . 6th - 1:40 PM

    看你这两天一直在研究代码,有个问题请教一下,我找的主题一般都不支持评论分页,你有这方面的教程没?谢谢

  5. 2009November . 6th - 1:41 PM

    我还在用着评论插件
    原生嵌套没搞定。。汗

  6. 2009November . 6th - 1:59 PM

    这个方法我已经用上了,嘿嘿

  7. 2009November . 6th - 2:29 PM

    看来你的主题越来越完善了。

  8. 2009November . 6th - 5:31 PM

    @要饭的
    你可以找个有评论分页的主题偷点代码试试,而且评论分页是可以用插件做出来的
    @A.shun
    原生嵌套评论做起来比较复杂

  9. 2009November . 6th - 6:05 PM

    请问记住用户信息用什么插件啊

  10. 2009November . 6th - 6:30 PM

    @网络生活
    不需要插件,用cookies

  11. 2009November . 6th - 8:27 PM

    我天,早知不看了,又看不懂 :cool:

  12. 2009November . 6th - 8:49 PM

    虽然不是很懂,可感觉会有用,收藏了再说

  13. 2009November . 6th - 9:44 PM

    代码达人~·
    强大

  14. 2009November . 6th - 10:38 PM

    这种方法真酷,看来我可以取消那个AJAX提交的插件换用代码实现了

  15. 2009November . 7th - 10:45 AM

    还是有点不明白!

  16. 2009November . 7th - 10:46 AM

    看到了,很酷

  17. 2009November . 7th - 11:34 AM

    我还没用上. 今晚来折腾

  18. 2009November . 7th - 9:11 PM

    @浮虾
    用这个方法比用插件好得多
    @超人
    希望你折腾成功

  19. 2009November . 7th - 9:19 PM

    看不懂,虽然我早已折腾过了

  20. 2009November . 7th - 10:54 PM

    测试一下 我是用插件实现的

  21. 2009November . 8th - 11:46 AM
    yzchbn

    我来看看 嘿嘿

  22. 2009November . 8th - 10:05 PM

    :) 我来体验一下。

  23. 2009November . 8th - 10:06 PM

    这里没有使用吗?怎么看不到效果?

  24. 2009November . 8th - 10:07 PM

    再来试一下,是不是用快捷键的原因

  25. 2009November . 8th - 10:07 PM

    确实是用快捷键就不是AJAX提交了….:mrgreen:

  26. 2009November . 8th - 10:29 PM

    @唏嘘一世
    居然被你发现了,今晚我还要完善一下

  27. 2009November . 9th - 12:18 PM

    嗯,貌似大家都是看Xiaorsz的那篇文章……
    这个我一直说弄都没时间弄……找个时间是得弄弄了~

  28. 2009November . 10th - 10:54 AM

    这个功能应该很实用吧,不过我这个菜鸟不敢轻举妄动啊!

  29. 2009November . 11th - 10:18 PM

    这个功能不错,谢谢了

  30. 2009November . 12th - 1:53 PM

    等我来试试~嘿嘿

  31. 2009November . 14th - 3:16 AM

    @Lxhome
    只要弄懂了原理就很容易了

  32. 2009November . 15th - 10:14 AM

    试一试效果看看~

  33. 2009November . 28th - 11:33 PM

    我来试试效果,准备给我的主题动动手术

  34. 2009December . 6th - 7:15 PM
    突起

    帮忙测试一下

  35. 2009December . 27th - 5:32 AM

    嘻嘻…收下了

Subscriber selector

Close