公开 API
主题和其他插件可以使用这些接口展示自己的评论列表、读者墙与排行榜。需要复用编辑器、登录、上传和验证码时,按开发者适配嵌入独立评论框即可,无需重写提交流程。
运行环境为 Halo 2.27.0 及以上。本页读者榜中的 website、emailHash、repliesCount 从 1.1.1 开始提供;旧版安装包可能不返回这些字段。接入时安装 1.1.1 或更高的兼容版本,或在调用方兼容字段缺失。
接口约定
插件查询接口的公共前缀为:
这些路径允许匿名读取。评论、回复、精选查询会根据当前登录用户的权限过滤:匿名访客看到公开内容,登录作者和具有相应权限的管理员可能看到更多内容。自定义前端不应把带登录态读取的结果缓存给其他访客。
读者榜始终按公开、已审核且未删除的内容聚合,不因请求者是管理员而纳入私密内容。接口不会直接返回原始评论邮箱或完整 IP;邮箱哈希的用途与局限见读者关联。
所有示例默认同站访问。登录态读取采用 credentials: 'include';接口错误时先检查 HTTP 状态,不能把错误响应当作分页对象使用。
评论列表
返回分页对象,主要结构为:
示例只保留与展示相关的字段,实际响应可能包含其他扩展信息。firstCommentName 在存在首条可见评论时返回,列表为空时可能省略。
置顶评论放在 pinnedItems,普通分页放在 items。total、totalPages 和 size 只针对普通主评论,置顶项不占分页名额;不要将置顶数量再次加入普通列表总数。withReplies=false 时不返回预加载的 replies 对象。
前端请求示例:
回复列表
路径中的 comment-xxx 是所属主评论的 metadata.name,不是被回复的另一条回复的 ID。构造路径时对该值使用 encodeURIComponent()。
返回同类分页对象,items 中是回复。回复按置顶优先、优先级升序、发表时间升序排列;此接口不接收评论列表的 sort 参数。
回复的 spec.commentName 指向所属主评论,spec.quoteReply 在回复另一条回复时指向被回复的回复。主评论不存在、已删除或当前用户无权查看时,返回 404,调用方不应继续展示该线程的历史缓存。
评论与回复的数据结构
这些是 HTTP 原始响应字段。评论框的 created 事件使用归一化结构,例如原始 metadata.name 对应 result.id,原始 stats.upvote 对应 result.stats.upvotes。接入自己的列表时,以使用的那一种结构为准。
精选评论
分页 items 仍沿用评论或回复结构,额外包含 targetType、parentName、subject,以及存在时的 featuredAt。targetType 为 comment 或 reply;parentName 在回复时为所属主评论 ID,主评论时为空字符串。适合主题展示精选评论卡片。
读者榜
周期采用 Halo 服务端时区的自然周期:本周从周一零点开始,本月从 1 日开始,本季从 1、4、7、10 月的第一天开始,本年从 1 月 1 日开始。all 表示全部。
响应
period 和 limit 为规范化后的实际参数,items 没有数据时为 [],有数据时也可能少于 limit。
统计规则
- 全站聚合已审核、非隐藏、未删除的主评论与回复;回复所属主评论也必须公开且未删除。
- 回复根据自己的发表时间计入周期,即使主评论发表于更早的周期。
- 按
commentCount降序,同数时按昵称不区分大小写升序排列;新增repliesCount不改变原来的总数含义和排序。 - 统计结果按周期缓存一分钟。新增内容、审核或资料变更可能稍后反映到榜单。
- 插件“读者排行”中的排除用户/邮箱设置,在每次请求时、截取人数之前生效,会自动补齐后续读者;不影响正常评论。
- 等级徽章按累计评论统计,与当前排行周期及名次独立;每次请求读取徽章快照,不属于上述榜单聚合缓存。
读者关联
匿名评论按规范化邮箱归并,登录用户按用户名归并。两类身份不会自动合并,同一邮箱可能在榜单中对应多行。因此 emailHash 是邮箱关联键,不是榜单行的唯一 ID。
匿名评论的哈希来自其评论邮箱;登录用户的哈希来自当前用户邮箱。没有邮箱、对应用户资料不可用时返回 null;邮箱变化后哈希也会变化。
主题可用 emailHash 对齐按相同规则生成的 spec.owner.annotations['email-hash'],正常邮箱数据也可与 Halo commentFinder 的哈希关联。历史邮箱数据包含额外首尾空白时,应先核对两侧的归一化规则。不要凭相同昵称合并身份,也不要在缺少哈希时把所有空值归并成一个读者。
SHA-256 哈希用于脱敏关联,并不是不可反推的匿名凭证。接口不直接公开原始邮箱;自定义前端应只展示业务需要的信息。
请求示例
榜单组件接入
不需要自己实现榜单 UI 时,可以在 Halo 文章编辑器中插入“评论读者榜(页面)”或“评论读者榜(侧边栏)”,也可直接在主题中放置:
页面榜单支持 1–50 人,侧边栏支持 1–10 人。两者均支持 accent-color、surface-color、text-color,也可由主题 CSS 变量 --comment-ranking-accent-color、--comment-ranking-surface-color、--comment-ranking-text-color 统一设置。show-header="false" 隐藏标题区,暗色外观跟随主题的暗色容器。
提交与兼容性
本插件的评论框使用 Halo 自身的评论提交接口:
它们属于 Halo API,和本页插件查询前缀不同。普通适配直接复用评论框,让组件处理登录、匿名信息、验证码、上传、错误提示与审核状态;不要向本插件的 GET /comments 查询路径发送创建请求。自己实现提交前端时,需要完整实现相应的 Halo 提交契约。
启用评论邮箱限制后,匿名提交使用受限邮箱时会在创建前返回 400,问题类型为 https://www.xhhao.com/probs/comment-email-rejected。主评论和回复均适用,不能靠直接调用 Halo 提交接口绕过。接入方应展示响应中的提示并保留草稿;不要将此错误误判为验证码错误或已提交成功。
/comments/ranking 作为公开接口供主题与插件使用,兼容扩展采用增加字段的方式;删除既有字段或改变既有含义时使用新的 API 版本。调用方应忽略未知字段,兼容可空值、空列表及旧版缺失字段。
昵称和摘要按文本渲染;website 作为链接使用前限制为 HTTP/HTTPS,外链按需添加 noopener noreferrer nofollow ugc。内容正文属于富文本,应采用接入方自己的安全渲染策略。