3.2.52: 新增「最近评论」挂件(替代 Comments Widget Plus 插件)#22

主题自带一个好看的最近评论挂件,用户不必再装插件。

新挂件 widget_recent_comments(id_base = yang_recent_comments):
- 头像 40px 圆形 + object-fit:cover,带 max-width/max-height 双保险
- 摘要按字符截断(mb_substr),先剥标签再压空白,不走 wp_html_excerpt(按字节切半个汉字)
- 作者 · 相对时间 · 文章标题三段各自成 span,不拼 i18n 句式
- 三层字号:摘要 15px / 作者 14px / 文章 13px(文章字号继承自 meta)
- 条间虚线,最后一条去掉
- 后台九项设置:标题、条数、头像、头像尺寸、摘要、摘要字数、排除 pingback、评论类型、文章类型

实现要点:
- CSS 不依赖 .k-main .sidebar 祖先,只依到 .w-comments 自身
  (3.2.51 的红线:带祖先的选择器在后台「外观→小工具」预览里一条不生效)
- .w-comments 自己不写 padding,交给 widget 基类,避免与其它挂件错位
- 只查 status=approve 且 post_status=publish,草稿文章评论不露出

同时修一个前后台不一致的 bug:
- form() 的 post_type 原来走 pick(),pick() 把空串当"没填"回落 'post'
  ⇒ 老实例(存空串)在后台下拉框显示「文章」,前台却按「全部类型」渲染。
  改为 widget() 与 form() 都直接读原值,两处都识别空串/any 为「全部类型」。

验证:行为 112/0 · 行为反证 25/25 + CSS 10/10 · 几何 50/0 ·
线上真实页面 30/0 · 静态反证 23/0 · 发布脚本 22 组反证全真红。
This commit is contained in:
2026-10-27 08:40:53 +08:00
parent c1dde099d7
commit baa1d16fd1
4 changed files with 592 additions and 2 deletions
+158
View File
@@ -1913,6 +1913,164 @@ button:focus {
line-height: 19px;
}
/* ══════════════════════════════════════════════════════════════════════
* 「最近评论」挂件(.w-comments)(3.2.52)
*
* ── 为什么自己做,不用插件 ────────────────────────────────────────────
* 原来装的是 Comments Widget Plus。它的三个问题都是实测出来的:
*
* ① 用 `_x('%1$s %2$son%3$s %4$s')` 拼句子,中文渲染成
* 「标题**上的**作者」(zh_CN.po 里 "on" 被译成"上的"),
* 而插件根本没带 zh_CN 语言包(languages/ 只有一个 .pot),
* 所以这句永远是英文语序套中文词。
* ② 文章标题 / 作者 / 摘要**三层同为 16px**,只能靠颜色区分;
* 而标题最长,首条实测 337×96(标题链接 332×50,折 2 行)。
* ③ 实例里 `avatar: false`,纯文字流没有任何视觉抓手。
*
* ── 这组规则的一条硬约束(3.2.51 的教训)────────────────────────────
* 🔴 选择器**只依赖 `.w-comments` 自身**,不写 `.k-main .sidebar .w-comments`。
* 3.2.51 的「个人简介撑爆」就是三段祖先选择器造成的:挂件在
* 后台「外观→小工具」预览里没有 `.k-main .sidebar` 那层祖先,
* 一组规则全部失效,头像按原图 2136px 铺开。
* **前台看起来正常,恰恰是把问题藏死的原因。**
* 🔴 所以这里**故意不写任何内边距规则**:白底与 15px/30px 内边距由
* 外层 `.widget` 提供(前台 `.k-main .sidebar .widget`,
* 后台由 WP 自己的挂件容器提供)。挂件本身不该管这些 ——
* 像 `.w-about` 那样去「对齐」内边距,就又把规则绑回祖先了。
*
* ── 信息层级(这是"漂亮"的全部含义)────────────────────────────────
* 摘要 15px #5a5a5a ← 主体,可点,整段链接到评论锚点
* 作者 14px #00a2ff ← 元信息,主色
* 文章 13px #999 ← 元信息,单行省略
* 时间 13px #999 ← 元信息
* 三层字号**必须不同**,插件"三层同为 16px"是它读起来像一坨的根本原因。
* ══════════════════════════════════════════════════════════════════════ */
/* 挂件内边距:不写。白底 + 15px/30px 由外层 `.widget` 提供,
* 与其它挂件(categories / archive 等)完全一致。理由见上面的 🔴。 */
.w-comments .yang-comment-list {
margin: 0;
padding: 0;
list-style: none;
}
/* 单条:flex 布局。
*
* 🔴 不用 float —— 插件用的是 `float:left` 的头像,长摘要下会出现
* "文字环绕到头像右侧再往下淌",元信息行钻进头像下方,整条错位。
* flex 的每一行都是独立盒子,不会出现环绕。 */
.w-comments .yang-comment-item {
display: flex;
align-items: flex-start;
padding: 12px 0;
border-bottom: 1px dashed #b4afaf;
}
/* 最后一条去掉分隔线 —— 跟 `.w-recommended .bookmark-item:last-child` 一致 */
.w-comments .yang-comment-item:last-child {
padding-bottom: 0;
border-bottom: none;
}
/* 头像:固定圆 + 裁切。
*
* 🔴 object-fit:cover 必须有:评论头像来自 Gravatar,可能是任意宽高比。
* fill(默认)会把人脸拉扁,none 会溢出。
* 🔴 flex-shrink:0 必须有:否则摘要很长时 flex 会把头像压扁(实测
* 40px 会被压到 8px 宽)。 */
.w-comments .yang-comment-avatar {
flex: 0 0 auto;
margin-right: 10px;
}
.w-comments .yang-comment-avatar img {
display: block;
width: 40px;
height: 40px;
max-width: 40px;
max-height: 40px;
object-fit: cover;
border-radius: 50%;
background-color: #f2f2f2;
}
/* 文字区:必须 min-width:0,否则长英文/长 URL 会撑破 flex 容器
* (flex 子项的默认 min-width 是 auto,等于"内容多宽就多宽")。 */
.w-comments .yang-comment-body {
flex: 1 1 auto;
min-width: 0;
}
/* 摘要:主体 */
.w-comments .yang-comment-text {
display: block;
color: #5a5a5a;
font-size: 15px;
line-height: 1.6;
text-decoration: none;
/* 中文长句无空格,必须 break-word,否则一个字都不换行直接溢出 */
overflow-wrap: break-word;
word-wrap: break-word;
}
.w-comments .yang-comment-text:hover {
color: #00a2ff;
}
/* 元信息行:作者 · 时间 · 文章标题 */
.w-comments .yang-comment-meta {
display: flex;
align-items: center;
flex-wrap: wrap;
margin-top: 4px;
color: #999;
font-size: 13px;
line-height: 1.5;
}
.w-comments .yang-comment-author {
color: #00a2ff;
font-size: 14px;
text-decoration: none;
}
.w-comments .yang-comment-sep {
margin: 0 5px;
color: #ccc;
}
.w-comments .yang-comment-time {
flex: 0 0 auto;
color: #999;
}
/* 文章标题:单行省略。
* min-width:0 同样是为了让 flex 允许它比内容窄。 */
.w-comments .yang-comment-post {
flex: 1 1 auto;
min-width: 0;
color: #999;
text-decoration: none;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.w-comments .yang-comment-post:hover {
color: #00a2ff;
}
/* 窄屏(侧栏整行显示,宽度充裕):让文章标题不必挤在一行里 */
@media (max-width: 991.98px) {
.w-comments .yang-comment-post {
flex: 1 1 100%;
white-space: normal;
overflow: visible;
text-overflow: clip;
}
}
.k-main .sidebar .w-recommended .bookmark-item {
display: block;
overflow: hidden;