用户 2026-10-27 提出:
现在我们来增加一个小挂件,就是显示最近评论的小挂件。主题里面原来 WordPress 自己原来就有一个的,但是那个实在是太丑了,所以我安装了一个插件。评论小工具加。但我感觉这应该是我们主题做的事。所以你就参考这个插件,然后做出一个漂亮的最近评论的小插件。
yangyq.net
inc/theme-widgets.php 第 21–34 行的 widgets_init() 里:
inc/theme-widgets.php
widgets_init()
$wp_widget = array( 'WP_Widget_Pages', 'WP_Widget_Meta', 'WP_Widget_Recent_Posts', 'WP_Widget_Recent_Comments', // ← 就是它 'WP_Widget_RSS', 'WP_Widget_Search', 'WP_Widget_Tag_Cloud', 'WP_Nav_Menu_Widget', ); foreach ($wp_widget as $wp_widget) { unregister_widget($wp_widget); }
所以后台根本看不到原生那个。这是 3.2.x 之前就有的决定(原生样式是裸 <ul><li>,跟主题完全不搭)。
<ul><li>
comments-widget-plus
wp-content/plugins/comments-widget-plus/
["about-3","search-3","posts-2","cwp-widget-3","categories-3","media_image-2"]
cwp-widget-3
avatar: false
excerpt: true
excerpt_limit: 35
limit: 10
order: DESC
exclude_pings: true
① 中文语序是断裂的。 插件用一条 _x() 拼句子:
_x()
_x( '%1$s %2$son%3$s %4$s', 'widgets', 'comments-widget-plus' ) // 作者 "on" 文章标题
英文读起来是「作者 on 文章标题」,翻成中文就成了:
「同步日历-我的第一款鸿蒙应用(鸿蒙CalDav客户端)上的 老杨」
—— 而插件根本没带 zh_CN 语言包(languages/ 目录下只有一个 .pot),这句是主题的翻译域在兜底,语序错位。
languages/
.pot
② 一条评论占 96px 高、混了 4 个信息层级全平铺。 实测每条 <li>:
<li>
#00a2ff
#333
#787878
三层同为 16px,只能靠颜色区分。而「文章标题」是最长的(实测首条宽 332px、折成 2 行 50px),把真正的评论内容挤到最下面。
③ 没有头像。 实例里 avatar: false(插件默认也是 false),纯文字流,视觉上没有任何抓手。
来自 readme.txt 与 form():
readme.txt
form()
limit
offset
DESC
ASC
post_type
widget_recent_comments
w-comments
名字要避开 WP 保留的 widget_recent_comments id_base —— 那个已被 unregister_widget 注销,但 id_base 冲突会让老数据复活。用 yang_recent_comments 作 id_base,CSS 类 w-comments,与现有 w-about / w-tags / w-search / w-ad / w-posts / w-recommended 保持一致。
unregister_widget
yang_recent_comments
w-about / w-tags / w-search / w-ad / w-posts / w-recommended
不是"把插件照抄一遍再加点 CSS",要按侧栏的视觉层级重做:
object-fit:cover
flex
float
float:left
#5a5a5a
#999
on
human_time_diff()
last-child
.w-recommended .bookmark-item
yang_widget_title()
post
3.2.51 刚踩过的坑:.k-main .sidebar .w-about .wrapper img 这种三段祖先选择器,在后台「外观→小工具」预览里一条都不生效。新挂件的规则只依赖 .w-comments 自身。
.k-main .sidebar .w-about .wrapper img
.w-comments
WP_Comment_Query
get_comment()
get_avatar()
pre_get_avatar
wp_comments
comment_approved_date_gmt
wp_cache_get/set('cwp_widget','widget')
add_action
overflow-wrap:break-word
<ul>
widget_about / widget_ad / widget_tags / widget_search / widget_posts
是新增一个此前主题里不存在的小工具(最近评论 w-comments),不是 #20 挂件一致性、#21 个人简介、#19 热点条数里任何一张的补充;可以单独验收、单独发版。
update.json 版本号已改为 3.2.52,readme.html 首行是 V3.2.52。 服务器主题目录仍是 3.2.51,未被覆盖 —— 需要你在 WP 后台「外观 → 主题」点升级。
update.json
readme.html
提交:baa1d16
baa1d16
主题新增 widget_recent_comments(id_base = yang_recent_comments),外观参照 ThemeZee 的 Comments Widget Plus,但只依到 .w-comments 自身写样式。
id_base = yang_recent_comments
前端长什么样
max-width
max-height
mb_substr
wp_html_excerpt
span
后台九项设置:标题、条数、显示头像、头像尺寸、显示摘要、摘要字数、排除 pingback、评论类型、文章类型
从插件版换过来要手动做一步:外观 → 小工具,把旧的插件版「最近评论」删掉,再拖入新版「最近评论」。两者 id_base 不同,不会互相覆盖,同时挂着会重复显示。
id_base
form() 里 post_type 原来走 pick(),而 pick() 把空串当"没填"、回落 'post'。
pick()
'post'
后果:老实例(存的是空串,表示「全部类型」)在后台下拉框显示「文章」,前台却按「全部类型」渲染。用户看到的是"我设置了只看文章,怎么页面评论还出别的",无从解释。
改成 widget() 和 form() 都直接读原值,两处都把空串 / any 认作「全部类型」。这个 bug 是本地预演抓出来的 —— 只测 widget() 一侧,前后台一致性永远成立。
widget()
any
_comments_test.php
_comments_falsify.php
_comments_geom.js
_comments_live_geom.js
_comments_live_falsify.js
反证这一版特意重写过架构:正本和"被改坏的副本"走同一套判据函数,比对失败条数增量。老写法另写一遍 grep 只证明了"注入改了字节",没证明判据有牙齿 —— 判据根本没被执行。
顺带在这轮抓掉 4 类判据缺陷(都会导致假绿或恒红):
.yang-comment-text
class="..."
echo
esc_html
升级后请在侧栏实际看一下这三件事:
确认没问题我再关这张单。
按用户确认收尾,交付见上条发布评论。
交付版本:3.2.52(主题自建「最近评论」挂件,替代 Comments Widget Plus)
用户已验收,关闭本单。
No dependencies set.
The note is not visible to the blocked user.
来源
用户 2026-10-27 提出:
现状盘点(已核对线上
yangyq.net,WP 7.1.3)一、主题已经注销了 WP 原生的最近评论挂件
inc/theme-widgets.php第 21–34 行的widgets_init()里:所以后台根本看不到原生那个。这是 3.2.x 之前就有的决定(原生样式是裸
<ul><li>,跟主题完全不搭)。二、当前用的是插件
comments-widget-plus1.3wp-content/plugins/comments-widget-plus/,实际代码 560 行(PHP 535 + CSS 25)["about-3","search-3","posts-2","cwp-widget-3","categories-3","media_image-2"]cwp-widget-3的配置:avatar: false、excerpt: true、excerpt_limit: 35、limit: 10、order: DESC、exclude_pings: true三、它「丑」的三个具体原因(都有实测依据)
① 中文语序是断裂的。 插件用一条
_x()拼句子:英文读起来是「作者 on 文章标题」,翻成中文就成了:
—— 而插件根本没带 zh_CN 语言包(
languages/目录下只有一个.pot),这句是主题的翻译域在兜底,语序错位。② 一条评论占 96px 高、混了 4 个信息层级全平铺。 实测每条
<li>:#00a2ff#333#787878三层同为 16px,只能靠颜色区分。而「文章标题」是最长的(实测首条宽 332px、折成 2 行 50px),把真正的评论内容挤到最下面。
③ 没有头像。 实例里
avatar: false(插件默认也是 false),纯文字流,视觉上没有任何抓手。四、插件的功能清单(本次要对齐的能力)
来自
readme.txt与form():limit、跳过offsetDESC/ASCpost_type需求
一、在主题里新建
widget_recent_comments挂件(w-comments)名字要避开 WP 保留的
widget_recent_commentsid_base —— 那个已被unregister_widget注销,但 id_base 冲突会让老数据复活。用yang_recent_comments作 id_base,CSS 类w-comments,与现有w-about / w-tags / w-search / w-ad / w-posts / w-recommended保持一致。二、视觉设计(这次的重点)
不是"把插件照抄一遍再加点 CSS",要按侧栏的视觉层级重做:
object-fit:cover防变形,配flex布局而不是float(插件的float:left在长文本下会出现文字环绕错位)。#5a5a5a),作者(14px / 主色#00a2ff)、文章标题(13px / 灰#999,单行省略)作为元信息放在下方一行。on。human_time_diff(),比绝对日期更适合侧栏。last-child去掉,跟.w-recommended .bookmark-item的做法一致。三、可配置项(照插件的功能对齐,但收敛到够用的范围)
yang_widget_title(),与其它挂件一致)post)四、CSS 规则不依赖祖先(写入本版硬约束)
3.2.51 刚踩过的坑:
.k-main .sidebar .w-about .wrapper img这种三段祖先选择器,在后台「外观→小工具」预览里一条都不生效。新挂件的规则只依赖.w-comments自身。五、性能
WP_Comment_Query一次取回,不逐条get_comment()。get_avatar()(WP 自带缓存与pre_get_avatar过滤)。wp_comments上有comment_approved_date_gmt索引,10 条的开销可忽略。插件的wp_cache_get/set('cwp_widget','widget')+ 三个add_action清缓存是过度设计,且它的缓存键是全局的(多个实例会互相污染)。验收标准
on的直译痕迹。overflow-wrap:break-word。<ul>)。不在本次范围
widget_about / widget_ad / widget_tags / widget_search / widget_posts。为什么单独建单
是新增一个此前主题里不存在的小工具(最近评论 w-comments),不是 #20 挂件一致性、#21 个人简介、#19 热点条数里任何一张的补充;可以单独验收、单独发版。
3.2.52 已发布到更新通道
update.json版本号已改为 3.2.52,readme.html首行是 V3.2.52。服务器主题目录仍是 3.2.51,未被覆盖 —— 需要你在 WP 后台「外观 → 主题」点升级。
提交:
baa1d16做了什么
主题新增
widget_recent_comments(id_base = yang_recent_comments),外观参照 ThemeZee 的 Comments Widget Plus,但只依到.w-comments自身写样式。前端长什么样
object-fit:cover,配max-width/max-height双保险,大图不会撑爆)mb_substr),不用wp_html_excerpt(那个按字节切,中文会切出半个字)span:作者 · 相对时间 · 文章标题,不拼成 "作者在《文章》中评论" 这种句式(i18n 时语序会错位)后台九项设置:标题、条数、显示头像、头像尺寸、显示摘要、摘要字数、排除 pingback、评论类型、文章类型
从插件版换过来要手动做一步:外观 → 小工具,把旧的插件版「最近评论」删掉,再拖入新版「最近评论」。两者
id_base不同,不会互相覆盖,同时挂着会重复显示。顺手修掉的一个真 bug
form()里post_type原来走pick(),而pick()把空串当"没填"、回落'post'。后果:老实例(存的是空串,表示「全部类型」)在后台下拉框显示「文章」,前台却按「全部类型」渲染。用户看到的是"我设置了只看文章,怎么页面评论还出别的",无从解释。
改成
widget()和form()都直接读原值,两处都把空串 /any认作「全部类型」。这个 bug 是本地预演抓出来的 —— 只测widget()一侧,前后台一致性永远成立。验证
_comments_test.php_comments_falsify.php_comments_geom.js_comments_live_geom.js_comments_live_falsify.js反证这一版特意重写过架构:正本和"被改坏的副本"走同一套判据函数,比对失败条数增量。老写法另写一遍 grep 只证明了"注入改了字节",没证明判据有牙齿 —— 判据根本没被执行。
顺带在这轮抓掉 4 类判据缺陷(都会导致假绿或恒红):
.yang-comment-text是 CSS 选择器写法,PHP 源码里是class="...",在正确代码上恒红echo(esc_html在下一行).w-comments起匹,祖先那截天然落在匹配范围外等你确认
升级后请在侧栏实际看一下这三件事:
确认没问题我再关这张单。
按用户确认收尾,交付见上条发布评论。
交付版本:3.2.52(主题自建「最近评论」挂件,替代 Comments Widget Plus)
用户已验收,关闭本单。