核心思路是 根据评论邮箱,统计该评论者已批准的评论数量,然后划分到不同的「等级」区间,最终输出一个带等级数字和提示文本的 HTML 标签。
核心代码部署
将以下核心代码添加到主题的 functions.php 文件中即可实现基础功能:
function get_comment_author_level($user_id, $comment_author_email) {
global $wpdb;
if ($user_id && user_can($user_id, 'manage_options')) {
return '<span class="post-author">博主</span>';
}
$email = sanitize_email($comment_author_email);
if (empty($email)) return '';
$comment_count = get_cached_comment_count($email);
$levels = [
499 => ['level' => 12, 'name' => '神话'],
369 => ['level' => 11, 'name' => '传奇'],
269 => ['level' => 10, 'name' => '无双'],
189 => ['level' => 9, 'name' => '泰斗'],
129 => ['level' => 8, 'name' => '宗师'],
89 => ['level' => 7, 'name' => '大侠'],
59 => ['level' => 6, 'name' => '豪侠'],
39 => ['level' => 5, 'name' => '侠客'],
24 => ['level' => 4, 'name' => '游侠'],
13 => ['level' => 3, 'name' => '少侠'],
6 => ['level' => 2, 'name' => '新锐'],
2 => ['level' => 1, 'name' => '新秀'],
];
$level = 0;
$level_name = '';
foreach ($levels as $threshold => $info) {
if ($comment_count >= $threshold) {
$level = $info['level'];
$level_name = $info['name'];
break;
}
}
if ($level === 0) return '';
return '<span class="com-level vip' . $level . '" title="' . esc_attr($level_name) . '"><strong>V</strong><sub>' . $level . '</sub></span>';
}
function get_cached_comment_count($email) {
global $wpdb;
$email = sanitize_email($email);
if (empty($email)) return 0;
$first = strtolower($email[0]);
$group = ctype_alnum($first) ? $first : 'other';
$cache_key = 'comment_counts_group_' . $group;
$comment_counts = get_transient($cache_key);
if ($comment_counts === false) {
$comment_counts = [];
}
if (!isset($comment_counts[$email])) {
$count = (int) $wpdb->get_var(
$wpdb->prepare(
"SELECT COUNT(comment_ID)
FROM $wpdb->comments
WHERE comment_approved = 1
AND comment_author_email = %s",
$email
)
);
$comment_counts[$email] = $count;
set_transient($cache_key, $comment_counts, 1 * HOUR_IN_SECONDS);
}
return $comment_counts[$email];
}
function clear_comment_count_cache($comment_id) {
$comment = get_comment($comment_id);
if (!$comment || empty($comment->comment_author_email)) return;
$email = sanitize_email($comment->comment_author_email);
if (empty($email)) return;
$first = strtolower($email[0]);
$group = ctype_alnum($first) ? $first : 'other';
$cache_key = 'comment_counts_group_' . $group;
$comment_counts = get_transient($cache_key);
if ($comment_counts !== false && isset($comment_counts[$email])) {
unset($comment_counts[$email]);
set_transient($cache_key, $comment_counts, 1 * HOUR_IN_SECONDS);
}
}
add_action('comment_post', function($comment_id, $comment_approved) {
if ($comment_approved == 1) {
clear_comment_count_cache($comment_id);
}
}, 10, 2);
add_action('wp_set_comment_status', function($comment_id, $status) {
clear_comment_count_cache($comment_id);
}, 10, 2);
add_action('edit_comment', function($comment_id) {
clear_comment_count_cache($comment_id);
}, 10, 1);
add_action('delete_comment', function($comment_id) {
clear_comment_count_cache($comment_id);
}, 10, 1);
评论数获取与缓存优化
评论数的统计如果每次都查数据库,会带来额外负担。为此我做了一个 分组缓存机制:
- 按邮箱首字母分组,把同一组的邮箱统计结果缓存在一个 transient 里;
- 这样避免了「每个邮箱单独缓存」或「所有邮箱一起缓存」的极端情况;
- 对于 评论量超过一万条 的博客,这种分组缓存能显著减少数据库查询压力。
缓存设置为 1小时自动清理。此外,我还在评论新增、编辑、删除、状态变更时,触发清理对应分组缓存,保证数据一致性。
如果你不在乎实时性,其实这一步也可以省略,因为评论等级的变化频率通常不高。去掉上面代码中 // 清理某邮箱的缓存 后面的代码就行。
评论者等级设计
我设计了 12个等级。12 是一个相对合适的数字:既能涵盖大部分评论者,又能为未来留出拓展空间。
在划分等级区间时,根据博客上 1.7万多条博友评论数据 做了统计:
- 绝大多数人的评论数量不多,所以前期的等级区间要小一些;
- 后期等级则逐渐拉大,避免升级过于频繁;
- 只有一条评论的用户不展示标识,所以区间从 2 开始;
- 同时预留 2-3 个高阶区间,给未来活跃评论者使用。
经过多次尝试,ChatGPT通过对数分布分析提供了合理的分区建议,我在此基础上进行了微调,得出了最终的分组数据。
等级命名与风格
每个人都可以根据喜好来命名等级,我个人喜欢武侠,所以设计了一个 江湖风格的升级体系:
新秀 → 新锐 → 少侠 → 游侠 → 侠客 → 豪侠 → 大侠 → 宗师 → 泰斗 → 无双 → 传奇 → 神话
依照 资历 → 实力 → 声望,逐级递进。
每个称呼都经过我精心斟酌,体现了江湖气息的升级体验。
样式与配色
在前端样式上,我定义了 .com-level 类,里面包含了等级标识和数字标记。示例代码如下:
颜色的思路是 逐级递增,从低阶的金属质感(黑铁、青铜、赤铜),逐步过渡到高阶的金色与紫金。
上面的代码用 V 字符代替图标,实际应用中你可以换成合适的图标。
将所有等级的图标放在一起看更有感觉一些。
模板调用
最后,在 comments.php 或自定义的评论函数中,比如在评论者的昵称旁边添加:
这样评论者的昵称后面就会带上等级标识,整个评论区会更有“江湖气息”。

原文地址
没有回复内容