WordPress主题同时支持嵌套评论与邮件回复

本着折腾到底不罢休的精神,又给博客做了个手术,这手术做的可不轻松,啃下了WP最艰难的部分。本次修改主要是为了支持嵌套回复,也是为了提高用户体验的一个重大举措吧,其实要纯粹的支持嵌套回复功能倒是简单,然而同时要正常使用ThinkAgainMail to Commenter插件来邮件回复的时候,问题就会随之而来了。昨晚折腾到半夜三点,终究是把问题给解决了。关键点在于如何让主题支持嵌套以及如何支持邮件回复。

让WP主题支持嵌套回复

首先要解决的是让主题嵌套回复,WP2.7版本后就支持此功能,这里可以参考mg12的WordPress 嵌套回复一文。最简单的方法是使用Wordpress自带的wp_list_comments()来自动解决,然而由于wp自带的wp_list_comments()代码稍嫌臃肿且无法自定义,这时候就需要在模板的function.php文件中来自定义评论显示方法,并在comments.php 中利用wp_list_comments(‘callback=custom_comments’)来显示自定义评论。

在自定义的评论显示方法中,只需要添加如下代码即可:

 <?php comment_reply_link(array_merge( $args, array('depth' => $depth, 'max_depth' => $args['max_depth']))) ?>

之后在后台设置中允许嵌套回复就可以了。

让回复功能支持Mail to Commenter插件的邮件回复

以上已经介绍了如何让主题支持嵌套回复了,然而以上的方法无法进行自定义,因此也就无法添加邮件回复所需的触发函数,于是我们需要对以上的方法进行适当的修改,通过研究代码,可以看到“回复”的链接实际上有类似这样的代码

onclick="addComment.moveForm('comment-<?php comment_ID() ?>','<?php comment_ID() ?>', 'respond', '<?php echo $post->ID; ?>');"

其中的’comment-< ?php comment_ID() ?>’会根据主题而不同例如WP自带的评论回复中该项就是’div-comment-‘。而另外一个’respond‘可能会根据不同主题不同,没有过多研究,各位可以自己尝试下。

也就是说自定义的时候只要修改下此处就好了,其中还要注意到的一个问题就是判断支持几层嵌套,当嵌套层数超出了WP后台设置的深度时则需要做相应处理,研究了WP的comment-template.php代码后,可以得到如下的方法判断是否已经超出嵌套层数:

if( $depth<get_option('thread_comments_depth'))

有了这些基础之后,就需要再为此回复链接带上邮件回复触发机制,大家知道Mail to Commenter插件会识别回复中是否存在@user 或者@user:来自动回复邮件,那么就需要为链接上加上一点Javascript代码让其有此功能,我研究了inove的JS代码后,借用如下:

RE_CON.reply('comment-author-<?php comment_ID() ?>','comment-<?php comment_ID() ?>','comment');

然后需要在主题的头部调用外部JS文件,此JS文件中加入如下代码:

(function() {
function $(id) {
	return document.getElementById(id);
}
window['RE'] = {};
window['RE']['$'] = $;
function reply(authorId, commentId, commentBox) {
	var author = RE.$(authorId).innerHTML;
	var insertStr = '<a href="#' + commentId + '">@'+ author.replace(/\t|\n|\r\n/g, "")+':</a> \n';
	insertReply(insertStr, commentBox);
}
function insertReply(insertStr, commentBox) {
	if(RE.$(commentBox) && RE.$(commentBox).type == 'textarea') {
		field = RE.$(commentBox);
	} else {
		alert("The comment box does not exist!");
		return false;
	}
	if (field.value.indexOf(insertStr) > -1) {
		alert("You've already appended this reply!");
		return false;
	}
	if (field.value.replace(/\s|\t|\n/g, "") == '') {
		field.value = insertStr;
	} else {
		field.value = field.value.replace(/[\n]*$/g, "") + '\n\n' + insertStr;
	}
}
window['RE_CON'] = {};
window['RE_CON']['reply'] = reply;
})();

之后,我们的嵌套回复于邮件回复功能就可以实现了。于是我最终的方法就如下了,也是本主题中用到的方法

<?php if(!function_exists('mailtocommenter_button')) {comment_reply_link(array_merge( $args, array('reply_text' => 'Reply', 'depth' => $depth, 'max_depth' => $args['max_depth'])));} else if(function_exists('mailtocommenter_button')&& $depth<get_option('thread_comments_depth')) { ?>
    <a  rel='nofollow' class='comment-reply-link' href="javascript:void(0);" onclick="addComment.moveForm('comment-<?php comment_ID() ?>','<?php comment_ID() ?>', 'respond', '<?php echo $post->ID; ?>');RE_CON.reply('comment-author-<?php comment_ID() ?>','comment-<?php comment_ID() ?>','comment'); ">
    <?php _e('Reply'); ?>
    </a>
    <?php } else { ?>
    <a  rel='nofollow' class='comment-reply-link' href="javascript:void(0);" onclick="RE_CON.reply('comment-author-<?php comment_ID() ?>','comment-<?php comment_ID() ?>','comment'); ">
    <?php _e('Reply'); ?>
    </a>
<?php }?>

其实在本人的修改中添加了对是否存在邮件回复插件的判断,其实如果是自己用的话不判断也可以,为了方便大家的使用才做了这样的处理。

Leave a Reply

Your email address will not be published. Required fields are marked *