3.2.49(#19 热点只显示一条)修完后,通读 inc/theme-widgets.php 全文(547 行)逐个挂件核对,剩下的 5 处问题。与 #19 是独立可分别验收的另一件事,故单独立单。
inc/theme-widgets.php
$args
register_sidebar() 已经注册了 before_title = '<div class="title">' / after_title = '</div>',但下列挂件完全不用 $args,标题要么硬编码、要么根本没有:
register_sidebar()
before_title = '<div class="title">'
after_title = '</div>'
widget_tags
echo '<div class="title">' . __('标签聚合', 'kratos') . '</div>';
widget_ad
title
widget_about
widget_posts
widget_search 是唯一有 title 字段的(但它自己手写 <div class="title">,也不读 $args)。
widget_search
<div class="title">
诉求:四个挂件都加 title 字段(form() 输入框 + update() 清洗 + 前台渲染),渲染时走 $args['before_title'] / after_title,让侧栏注册的版式统一生效。
form()
update()
$args['before_title']
after_title
线上真实栅格(.k-main > .container > .row > .col-lg-8 + .col-lg-4.sidebar)逐视口实测:
.k-main > .container > .row > .col-lg-8 + .col-lg-4.sidebar
根因在 assets/css/kratos.css 的 @media screen and (max-width: 1310px):它把 .k-main .sidebar .w-tags .item a 的宽度从 164px 改成 110px。但侧栏在这个区间并没有变窄(仍 336.7px 内容区),于是窗口变窄 1px、列数反而从 2 变成 3。
assets/css/kratos.css
@media screen and (max-width: 1310px)
.k-main .sidebar .w-tags .item a
违反的是一条基本性质:视口越窄,每行能放的元素数不该更多。
诉求:列数只由容器宽度决定,随视口同向变化(单调不增)。不要靠「再调一个魔法数字」糊过去——现在的 164/110 就是两次魔法数字叠加的结果。
widget() 里同一套标签页导航写了两份(桌面带图标、手机不带图标):
widget()
<div class="nav nav-tabs d-none d-xl-flex" id="nav-tab"> ← 桌面 <a id="nav-new-tab" ...> <a id="nav-hot-tab" ...> <a id="nav-random-tab" ...> </div> <div class="nav nav-tabs d-xl-none" id="nav-tab"> ← 手机 <a id="nav-new-tab" ...> <a id="nav-hot-tab" ...> <a id="nav-random-tab" ...> </div>
nav-tab、nav-new-tab、nav-hot-tab、nav-random-tab 各出现两次 ⇒ HTML 非法;aria-labelledby="nav-new-tab" 只能指到第一份。而且挂件可以添加多个实例,多实例时 id 撞得更彻底。
nav-tab
nav-new-tab
nav-hot-tab
nav-random-tab
aria-labelledby="nav-new-tab"
诉求:id 全局唯一。桌面/手机两份导航合并成一份,靠 CSS 在窄屏隐藏图标。
widget_search::widget() 硬编码 id="searchform" / id="search" / id="searchsubmit"。主题/核心的另一个搜索表单也用 searchform 时会撞;挂两个搜索挂件同样撞。
widget_search::widget()
id="searchform"
id="search"
id="searchsubmit"
searchform
诉求:id 唯一化(或改用 class / aria-label),并补上可访问性所需的 label 关联。
aria-label
// widget_ad '<a href="' . $url . '" ...><img src="' . $image . '"><div class="prompt">' . $subtitle . '</div></a>' // ↑ 未 esc_url ↑ src 的值没有引号 // widget_about '<div class="background" style="background:url(' . $background . ') no-repeat center center;...' // ↑ url() 里没引号
url() 里不加引号,只要路径含空格、括号、单引号就会截断;src= 的值不加引号,URL 里一旦有空格,后半截会被解析成另一个属性。
url()
src=
诉求:URL 加引号并 esc_url(),文本 esc_html(),补 alt。
esc_url()
esc_html()
alt
before_title
id
src
#19 只处理「热点标签页为什么只出 1 条」(候选池被最近30天时间窗卡住),改的是排序与取数逻辑。本单是另外 5 处独立缺陷:标题可配置性、标签列数随屏宽反转(CSS 媒体查询)、重复 HTML id、搜索框固定 id、图片 URL 引号与转义。两者文件区域不同(#19 在 most_comm_posts()/yang_hot_posts(),本单在 widget_*::widget() 与 kratos.css),可各自单独验收,不属于同一需求的补充。#15~#18 是归档页/评论区/短代码,与侧栏挂件无关。
提交:8367231(main 已推送) 升级方式:WP 后台 → 外观 → 主题 → 检查更新 → 升到 3.2.50(服务器 wp-content/themes/kratos_yang/ 未被覆盖,仍为 3.2.49,等你在后台点升级)
8367231
main
wp-content/themes/kratos_yang/
① 标题不读 $args(4 个挂件标题后台改不了)
新增 yang_widget_title($args, $instance, $fallback, $id_base),5 个挂件统一走它:
yang_widget_title($args, $instance, $fallback, $id_base)
$instance['title']
$fallback
widget_title
<div class="title"></div>
四个挂件的 update() 补 title、form() 补输入框 + 「留空则不显示标题」说明。 widget_tags 留空回落「标签聚合」,老站点显示不变。
② 标签列数随屏宽反转(1440 一列、1180 反而两列)
逐视口实测线上真实栅格,真实断点不在 1440/1180,而在 1311→1310:
根因:@media (max-width:1310px) 只把格子压窄、不改侧栏宽度(侧栏 992px 以上恒为容器 1/3),格子变小了自然能塞更多。
@media (max-width:1310px)
改为 width: calc(50% - 2px) + 父容器 font-size:0(消掉 inline-block 之间的空白宽度),1310 断点里删掉这两条 110px 规则(分类/归档的 110px 不是网格,保留)。 判据守的是「列数单调不增」,不是「某视口恰好两列」 —— 后者等于把当前 bug 固化成期望值。
width: calc(50% - 2px)
font-size:0
③ 重复 id nav-tab(桌面一份、手机一份)
两份导航合并为一份,id 全部带实例后缀:yang_widget_uid($this) 取 $widget->id(如 widget_posts-2),输出 {uid}-tab / {uid}-new 等,aria-controls / aria-labelledby 同步指向真实 id。两个实例并用也不撞。
yang_widget_uid($this)
$widget->id
widget_posts-2
{uid}-tab
{uid}-new
aria-controls
aria-labelledby
④ 搜索框固定 id(searchform / search / searchsubmit)
search
searchsubmit
同样改为 {uid}-form / {uid}-field / {uid}-submit,并补 <label class="sr-only" for="{uid}-field">搜索</label>。
{uid}-form
{uid}-field
{uid}-submit
<label class="sr-only" for="{uid}-field">搜索</label>
⑤ 图片 URL 未加引号 + 未转义
src / href 一律加引号 + esc_url(),alt 用 wp_strip_all_tags + esc_attr,简介用 nl2br(esc_html())。
href
wp_strip_all_tags
esc_attr
nl2br(esc_html())
自曝一个我自己写出来的 bug:一开始写成 esc_url() 套在 esc_attr() 里 = 双重转义,& 变 &amp;,CSS 里拿到字面量 amp,背景图 404。是 _widgets_consistency.php 的「背景 URL 完整」判据抓出来的。改为 url() 内部用 esc_url_raw()(只做协议/字符清洗,不入实体),整个 style 属性交给 esc_attr() 统一转义一次。
esc_attr()
&
&amp;
amp
_widgets_consistency.php
esc_url_raw()
style
顺带把侧栏标签页图标在 <1200px 隐藏,避免三个 tab 挤在一起。
<1200px
_widgets_consistency_falsify.php
_widgets_hot_test.php
_widgets_hot_falsify.php
_widgets_hot_geom.js
_widgets_ids_dom.js
_widgets_visual20.js
naturalWidth>0
_widgets_icon_wide.js
_widgets_tags_geom.js
发布链路:包内 7 条改动逐条回读 · HTTP 下载 md5 一致 · unzip -t 通过 · update.json 最后才落版本号。
unzip -t
update.json
等你升级到 3.2.50 并确认这五处没问题后,我再关闭本工单。
按用户确认收尾,交付见上条发布评论。
交付版本:3.2.50(挂件标题可配、标签列数、重复 id、URL 转义 5 处一并修)
用户已验收,关闭本单。
No dependencies set.
The note is not visible to the blocked user.
来源
3.2.49(#19 热点只显示一条)修完后,通读
inc/theme-widgets.php全文(547 行)逐个挂件核对,剩下的 5 处问题。与 #19 是独立可分别验收的另一件事,故单独立单。需求清单
一、四个挂件的标题在后台改不了(不读
$args)register_sidebar()已经注册了before_title = '<div class="title">'/after_title = '</div>',但下列挂件完全不用$args,标题要么硬编码、要么根本没有:widget_tagsecho '<div class="title">' . __('标签聚合', 'kratos') . '</div>';硬编码,后台无输入框widget_adtitle字段widget_aboutwidget_postswidget_search是唯一有title字段的(但它自己手写<div class="title">,也不读$args)。诉求:四个挂件都加
title字段(form()输入框 +update()清洗 + 前台渲染),渲染时走$args['before_title']/after_title,让侧栏注册的版式统一生效。二、标签聚合的列数随屏宽反转(窄屏反而多一列)
线上真实栅格(
.k-main > .container > .row > .col-lg-8 + .col-lg-4.sidebar)逐视口实测:根因在
assets/css/kratos.css的@media screen and (max-width: 1310px):它把.k-main .sidebar .w-tags .item a的宽度从 164px 改成 110px。但侧栏在这个区间并没有变窄(仍 336.7px 内容区),于是窗口变窄 1px、列数反而从 2 变成 3。违反的是一条基本性质:视口越窄,每行能放的元素数不该更多。
诉求:列数只由容器宽度决定,随视口同向变化(单调不增)。不要靠「再调一个魔法数字」糊过去——现在的 164/110 就是两次魔法数字叠加的结果。
三、
widget_posts有重复 idwidget()里同一套标签页导航写了两份(桌面带图标、手机不带图标):nav-tab、nav-new-tab、nav-hot-tab、nav-random-tab各出现两次 ⇒ HTML 非法;aria-labelledby="nav-new-tab"只能指到第一份。而且挂件可以添加多个实例,多实例时 id 撞得更彻底。诉求:id 全局唯一。桌面/手机两份导航合并成一份,靠 CSS 在窄屏隐藏图标。
四、搜索框写死 id
widget_search::widget()硬编码id="searchform"/id="search"/id="searchsubmit"。主题/核心的另一个搜索表单也用searchform时会撞;挂两个搜索挂件同样撞。诉求:id 唯一化(或改用 class /
aria-label),并补上可访问性所需的 label 关联。五、图片 URL 未加引号,且缺转义
url()里不加引号,只要路径含空格、括号、单引号就会截断;src=的值不加引号,URL 里一旦有空格,后半截会被解析成另一个属性。诉求:URL 加引号并
esc_url(),文本esc_html(),补alt。验收标准
before_title/after_title版式显示;清空则不输出标题节点。id无重复(用 DOM 解析器统计,不靠肉眼);一个页面挂两个「文章聚合」也不撞。src与url()都不被截断。为什么单独建单
#19 只处理「热点标签页为什么只出 1 条」(候选池被最近30天时间窗卡住),改的是排序与取数逻辑。本单是另外 5 处独立缺陷:标题可配置性、标签列数随屏宽反转(CSS 媒体查询)、重复 HTML id、搜索框固定 id、图片 URL 引号与转义。两者文件区域不同(#19 在 most_comm_posts()/yang_hot_posts(),本单在 widget_*::widget() 与 kratos.css),可各自单独验收,不属于同一需求的补充。#15~#18 是归档页/评论区/短代码,与侧栏挂件无关。
3.2.50 已发布到主题更新通道
提交:
8367231(main已推送)升级方式:WP 后台 → 外观 → 主题 → 检查更新 → 升到 3.2.50(服务器
wp-content/themes/kratos_yang/未被覆盖,仍为 3.2.49,等你在后台点升级)五处改动
① 标题不读
$args(4 个挂件标题后台改不了)新增
yang_widget_title($args, $instance, $fallback, $id_base),5 个挂件统一走它:$instance['title'],空则回落$fallbackwidget_title过滤器(兼容别的插件改标题)$args['before_title']/after_title(所以换侧栏样式也跟着变)<div class="title"></div>)四个挂件的
update()补title、form()补输入框 + 「留空则不显示标题」说明。widget_tags留空回落「标签聚合」,老站点显示不变。② 标签列数随屏宽反转(1440 一列、1180 反而两列)
逐视口实测线上真实栅格,真实断点不在 1440/1180,而在 1311→1310:
根因:
@media (max-width:1310px)只把格子压窄、不改侧栏宽度(侧栏 992px 以上恒为容器 1/3),格子变小了自然能塞更多。改为
width: calc(50% - 2px)+ 父容器font-size:0(消掉 inline-block 之间的空白宽度),1310 断点里删掉这两条 110px 规则(分类/归档的 110px 不是网格,保留)。判据守的是「列数单调不增」,不是「某视口恰好两列」 —— 后者等于把当前 bug 固化成期望值。
③ 重复 id
nav-tab(桌面一份、手机一份)两份导航合并为一份,id 全部带实例后缀:
yang_widget_uid($this)取$widget->id(如widget_posts-2),输出{uid}-tab/{uid}-new等,aria-controls/aria-labelledby同步指向真实 id。两个实例并用也不撞。④ 搜索框固定 id(
searchform/search/searchsubmit)同样改为
{uid}-form/{uid}-field/{uid}-submit,并补<label class="sr-only" for="{uid}-field">搜索</label>。⑤ 图片 URL 未加引号 + 未转义
src/href一律加引号 +esc_url(),alt用wp_strip_all_tags+esc_attr,简介用nl2br(esc_html())。顺带把侧栏标签页图标在
<1200px隐藏,避免三个 tab 挤在一起。验证结果(全绿)
_widgets_consistency.php$args· id 唯一 · URL 引号与转义 · 后台表单_widgets_consistency_falsify.php_widgets_hot_test.php_widgets_hot_falsify.php_widgets_hot_geom.js_widgets_ids_dom.js_widgets_visual20.jsnaturalWidth>0、标题装饰线、标签等宽、tab 点击真生效_widgets_icon_wide.js_widgets_tags_geom.js发布链路:包内 7 条改动逐条回读 · HTTP 下载 md5 一致 ·
unzip -t通过 ·update.json最后才落版本号。等你升级到 3.2.50 并确认这五处没问题后,我再关闭本工单。
按用户确认收尾,交付见上条发布评论。
交付版本:3.2.50(挂件标题可配、标签列数、重复 id、URL 转义 5 处一并修)
用户已验收,关闭本单。