Home » Code » WordPress主题开发Part6——评论

WordPress主题开发Part6——评论

WP可以控制是否允许给每篇文章或每个独立页面进行评论。

显示评论列表

显示评论列表,WP有专门的评论模板,命名为comments.php。能不能不使用评论模板直接在文章模板中列出?答案是不能!这可以说是一个坑。因为与评论相关的很多函数都只有在调用了comments_template()之后才有数据,比如判断是否有评论的have_comments(),获得评论数量的get_comments_number()等。一开始不懂情况就入坑了,情况说明可以参考这里。comments_template()就是载入评论模板comments.php的。

在comments.php中,使用wp_list_comments()来将评论输出。

显示评论框

显示评论框,使用comment_form即可直接输出默认的评论框。

添加额外信息

默认有author(作者)、email(邮箱)、url(网站,可选)、comment(评论)这4个字段。如果你想添加自定义的字段,比如加个phone(手机),也是可以的。办法是在comment_form_default_fields这个filter Hook上挂载函数,将你的字段添加进来却可。例如:

function my_add_comment_form_field($fields)
{
	global $post;
	if ($post->post_name === 'contract_us')//只在这个页面加
	{
		$phone = '<p class="comment-form-phone"><label for="phone">手机<span class="required">*</span></label> <input id="phone" name="phone" type="number" value="" size="30" aria-describedby="phone-notes" aria-required="true" required="required"></p>';
		$fields['phone'] = $phone;
	}
	return $fields;
}
add_filter('comment_form_default_fields', 'my_add_comment_form_field');

这样子之后,评论框就多了“手机”这个字段。但这显示只是表单上有而已,添加评论的时候并不会存到数据库。要存到数据库那就是放到wp_commentmeta表中,方法是add_comment_meta(),用到的action Hook是wp_insert_comment。意思是在评论插入wp_comments表后立即将额外信息“手机”插到wp_commentmeta表中。例如:

function lzgl_insert_custom_comment_field($commentID)
{
	if (!empty($_POST['phone']) && ctype_digit($_POST['phone']))
	{
		$add = add_comment_meta($commentID, 'comment_phone', $_POST['phone']);
		if ($add === FALSE)
		{
			wp_die('添加phone:'.$_POST['phone'].'失败!', 200);
		}
	}
}
add_action('wp_insert_comment', 'lzgl_insert_custom_comment_field');

插入到commentmeta表中的数据,获取是get_commentmeta(),跟get_postmeta()一样的用法。

更进一步,如果要先验证呢,也就是跟WP验证作者、邮箱等一样的后台验证,手机验证不通过评论也不插入,这又要如何做?首先,思路肯定还是那一套,找action Hook来挂函数。可以到官方代码参考中搜索“comment”的Hook,看能不能找到可用的,或者直接看表单提交的目标文件wp_comments_post.php的源代码,可以看到在大约89行就有了do_action(),结果很明显就是在pre_comment_on_post这个action Hook上动手了。示例如下:

function lzgl_verify_custom_comment_field($comment_post_ID)
{
	if (!empty($_POST['phone']) && preg_match('/^[\d]{11}$/i', trim($_POST['phone'])))
	{
		return true;
	}
	wp_die('<strong>手机不合法:'.$_POST['phone'].'</strong>');
}
add_action('pre_comment_on_post', 'lzgl_verify_custom_comment_field');

能添加一个额外信息也得可以在后台显示并编辑才完美,在这里再把显示也弄一下,编辑就算了,基本没有必要。

//将自定义字段添加到评论管理页面table的header头
function lzgl_display_custom_comment_field_manage_table_head($columns)
{
	$newColumns = array_slice($columns, 0, 3);
	$keys = array_keys($columns);
	$values = array_values($columns);
	$newColumns['comment_phone'] = '手机';
	$newColumns[end($keys)] = end($values);
	return $newColumns;
}
add_filter('manage_edit-comments_columns', 'lzgl_display_custom_comment_field_manage_table_head');

//将自定义字段添加到评论管理页面table的tr行
function lzgl_display_custom_comment_field_manage_table_row($columnName, $commentID)
{
	echo get_comment_meta($commentID, $columnName, true);
}
add_action('manage_comments_custom_column', 'lzgl_display_custom_comment_field_manage_table_row', 10, 2);

以上代码参考自这里。这一块主要是不知道manage_edit-comments_columns这个往table头添加信息的这个filter,官方找不到。其实它是在wp-admin/includes/scree.php中的第一个函数get_column_headers()里边,这种好像比较特别一点。

wp_manage_comments
至于删除,照着往deleted_comment上操作即可。

可以看到,为评论添加额外信息就用到了这么多个Hook,整个WP的运行过程就是运行大量的action Hook(动作钩子)和filter Hook(过滤钩子),也正是有了这么多的Hook,才使得WP有了这么强的扩展能力。

小Tip:评论的gravatar头像有可能因墙的原因显示很慢甚至出不来,除了使用插件外,为get_avatar这个filter Hook挂载过滤函数将地址换为国内镜像即可轻松解决,如替换为多说的服务器:

function lzgl_fix_avatar_addr($avatar)
{
	$avatar = str_replace(array('www.gravatar.com', '0.gravatar.com', '1.gravatar.com', '2.gravatar.com'), 'gravatar.duoshuo.com', $avatar);
	return $avatar;
}
add_filter('get_avatar', 'lzgl_fix_avatar_addr');

就这么一替换,可能为网站提速不少,包括前后台。

One comment

Leave a Reply

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

*

Time limit is exhausted. Please reload CAPTCHA.