分类挂件下拉面板列出全部层级并缩进 #24
需求(2026-10-27):把多级目录也放进去,现在只显示第一级,把其他的 也放进去,注意缩进。线上实测 29 个分类(8 一级 + 21 二级,无第三层), 因此面板从「只列一级」改成「有几层列几层」。 inc/theme-widgets.php - get_tree() 从写死两层改成任意深度递归。带 $seen 已访问集合 + $max_depth=10 双重保护:parent 成环时只跳过、不抛异常 —— 侧栏 挂件白屏会把整站带下去,宁可少显示一条也不能崩。 - 排序递归到所有层(原来只排前两层,第三层往后顺序与「按文章数排」不一致)。 - 新增 find_name():触发条文案与面板渲染共用同一套遍历。原来两段各自 硬编码两层,层数一变必漏一处。 - 新增 render_level():widget() 面板改成单次递归调用。关闭 children 时把 children 清空交给同一函数,不另写一份循环 —— 两份循环必然漂移。 - 下一层 <ul> 放在本层 li 内部(HTML 里 ul 的直接子元素只能是 li)。 - children 兜底值 false → true,**两处**(widget 第 1501 行、form 第 1701 行)。线上实例 categories-3 没有这个键 ⇒ 走兜底 ⇒ 用户零操作生效。 assets/css/kratos.css - .yang-cats-item 加 flex-wrap:wrap;子级 ul 用 flex:0 0 100% 独占 一整行,落在父级 li 的内容盒里 ⇒ 缩进逐层累加且所有层共用一个右边界。 - 缩进只由子级 li 的 padding-left 给,**子级 ul 的 padding-left 归零**。 第一版两处都给了 12px,几何实测每层缩进 24px(stepPx=[24,24,18]), 第 3 层名字只剩 148px,收敛规则也一起失效。 - 第 4 层起收缩到 6px([style*="--cat-d:3"] 起),避免深层吃光面板宽度。 - 每层 padding-right 一律 0,右侧 12px 只由顶层统一给 ⇒ 任意深度的 数字右沿都在同一竖线(数字要竖着比大小,错开一列就没法比)。 assets/css/kratos.min.css 重新压缩;style.css 版本号 → 3.2.56。 验证 - 端到端(真实 WordPress):120 通过 / 0 失败;旧代码 100 / 17 - 反证 20 组(R1~R19 + R13b)全部命中 - 视觉几何(线上真实页面):56 通过 / 0 失败 - 打包内容自检 26 项全过;发布判据 79 条全过 - 发布:update.json → 3.2.56,md5 0aa90b30e76d754de41febcb9271ddef - 红线:服务器主题目录仍 3.2.55(未覆盖),等用户在后台点升级
This commit is contained in:
+75
-22
@@ -2250,6 +2250,15 @@ button:focus {
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
|
/* 🔴 flex-wrap 是 3.2.56 支撑"任意层级"的关键:
|
||||||
|
*
|
||||||
|
* 有子级的 li 里除了 <a> + <span>,还多一个直接子元素
|
||||||
|
* `<ul class="yang-cats-children">`。默认 nowrap 时它会挤进同一行,
|
||||||
|
* 把名字和数字挤扁;
|
||||||
|
* 这里允许换行,再让子级 ul `flex: 0 0 100%` 独占整行
|
||||||
|
* ⇒ 子级自然落到父级名字下面,且**父级 li 的 padding-left
|
||||||
|
* 就成了下一层的缩进基准**(嵌套在内容盒里,缩进逐层累加)。 */
|
||||||
|
flex-wrap: wrap;
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
list-style: none;
|
list-style: none;
|
||||||
@@ -2305,34 +2314,73 @@ button:focus {
|
|||||||
color: #00a2ff;
|
color: #00a2ff;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ── 子分类(可选,默认关)──────────────────────────────────────────────
|
/* ── 子分类:任意层级(3.2.56 从"只有两层"改成"有几层列几层")──────────
|
||||||
*
|
*
|
||||||
* 缩进 + 字号轻一档。不加竖线:3.2.54 加过,但那是"常显树"的视觉语言;
|
* 🔴 结构(每层都一样,嵌套在父级 li 内部):
|
||||||
* 在浮层面板里加竖线会让本就不宽的面板更挤,缩进已经足够表达层级。 */
|
*
|
||||||
|
* <ul class="yang-cats-list">
|
||||||
|
* <li class="yang-cats-item">
|
||||||
|
* <a/><span/>
|
||||||
|
* <ul class="yang-cats-children">
|
||||||
|
* <li class="yang-cats-item"> <a/><span/> … </li>
|
||||||
|
* </ul>
|
||||||
|
* </li>
|
||||||
|
* </ul>
|
||||||
|
*
|
||||||
|
* 🔴 缩进与对齐是怎么同时成立的(这里的算式必须写清楚,改坏很难查):
|
||||||
|
*
|
||||||
|
* · 子级 ul 是 li 的 flex 子项,`flex: 0 0 100%` ⇒ 独占一行。
|
||||||
|
* · 因嵌套在 li 的**内容盒**里,所有层共用一个右边界;
|
||||||
|
* · 每层 li 只给 **padding-left**(缩进),**padding-right 一律 0**,
|
||||||
|
* 右侧内边距由最外层的 `.yang-cats-list > .yang-cats-item` 统一给 12px。
|
||||||
|
*
|
||||||
|
* ⇒ 任意深度的数字右沿都在同一竖线上(数字要竖着比大小)。
|
||||||
|
* 3.2.55 就是子级又写了一遍 padding-right,叠成 24px、父子错开 12px。
|
||||||
|
*
|
||||||
|
* 🔴 缩进量取 12px/层:面板 250px 宽,减去右侧 12px、数字胶囊约 34px、
|
||||||
|
* 名字与数字间 8px,留给名字约 196px。三级时名字还剩 172px,
|
||||||
|
* 中文 15px 字号约能放 11 个字 —— 够用。到四五级会明显挤,
|
||||||
|
* 所以 CSS 里对超深层的缩进做了收敛(见下面的 `--cat-d` 规则)。
|
||||||
|
*
|
||||||
|
* 🔴🔴 缩进只能由一个地方给,不能 ul 和 li 各给一次(3.2.56 实测踩过):
|
||||||
|
* 第一版 `.yang-cats-children { padding-left: 12px }` 加
|
||||||
|
* `.yang-cats-children > .yang-cats-item { padding-left: 12px }`
|
||||||
|
* ⇒ 每层实际缩进 **24px**,几何实测 stepPx=[24,24,18],
|
||||||
|
* 第 3 层名字就只剩 148px,比设计预期少一半。
|
||||||
|
* 收敛规则也一起失效(12+6=18,看着像没收敛)。
|
||||||
|
* ⇒ **子级 ul 的 padding-left 归零,缩进全部由子级 li 的 padding-left 给。**
|
||||||
|
* 这样一个数字管一件事,收敛规则也能精确生效。 */
|
||||||
.w-cats .yang-cats-children {
|
.w-cats .yang-cats-children {
|
||||||
/* 子级整段缩进 12px,与父级名字错开一档 */
|
/* 独占一整行:父级名字在上,子级列表在下 */
|
||||||
padding: 0 0 6px 12px;
|
flex: 0 0 100%;
|
||||||
|
width: 100%;
|
||||||
|
margin: 0;
|
||||||
|
/* 🔴 padding-left 必须 0:缩进由子级 li 独立给,两处都加会翻倍 */
|
||||||
|
padding: 0;
|
||||||
background-color: #fcfcfc;
|
background-color: #fcfcfc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 🔴 子级 li 的**右侧**内边距必须是 0,不能跟着父级写 12px。
|
/* 每层子级 li:只留左缩进,右侧归零(右侧由最外层统一给 12px) */
|
||||||
*
|
|
||||||
* 这是 3.2.55 几何实测抓出来的真缺陷(不是量法问题):
|
|
||||||
*
|
|
||||||
* 父级数字右边界距面板内沿 12px
|
|
||||||
* 子级数字右边界距面板内沿 24px ← 多出整整 12px
|
|
||||||
*
|
|
||||||
* 原因:子级 `<ul>` 嵌在父级 `<li>` 里,而父级 li 已经有
|
|
||||||
* `padding: 0 12px`,那 12px 已经把子级 ul 的右边界推进去了;
|
|
||||||
* 子级 li 再写一次 12px ⇒ 叠加成 24px。
|
|
||||||
*
|
|
||||||
* 后果很直观:**数字排不成一列**。面板里父级数字靠右、
|
|
||||||
* 子级数字齐刷刷往左缩 12px,看着像两家不同的列表拼在一起。
|
|
||||||
* 分类数字是要竖着比的(哪个分类文章多),错开一列就没法比。
|
|
||||||
*
|
|
||||||
* ⇒ 子级只留左缩进(由 ul 的 padding-left 提供),右侧归零。 */
|
|
||||||
.w-cats .yang-cats-children > .yang-cats-item {
|
.w-cats .yang-cats-children > .yang-cats-item {
|
||||||
padding: 0;
|
padding: 0 0 0 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 🔴 第 4 层起缩进收敛:再往下每层只加 6px。
|
||||||
|
*
|
||||||
|
* 理由:面板宽度固定,缩进按 12px 线性累加的话,
|
||||||
|
* 第 5 层只剩 130px 出头,中文名字挤成两三个字一行,反而更难读。
|
||||||
|
* 分层收敛让深层"还能看出层级"但不至于把空间吃光。
|
||||||
|
*
|
||||||
|
* 用 `--cat-d`(渲染时写的真实深度)选层级,而不是靠选择器数嵌套层数 ——
|
||||||
|
* 后者写死了就只能支持固定层数,又回到 3.2.55 的老问题。 */
|
||||||
|
.w-cats .yang-cats-children > .yang-cats-item[style*="--cat-d:3"],
|
||||||
|
.w-cats .yang-cats-children > .yang-cats-item[style*="--cat-d:4"],
|
||||||
|
.w-cats .yang-cats-children > .yang-cats-item[style*="--cat-d:5"],
|
||||||
|
.w-cats .yang-cats-children > .yang-cats-item[style*="--cat-d:6"],
|
||||||
|
.w-cats .yang-cats-children > .yang-cats-item[style*="--cat-d:7"],
|
||||||
|
.w-cats .yang-cats-children > .yang-cats-item[style*="--cat-d:8"],
|
||||||
|
.w-cats .yang-cats-children > .yang-cats-item[style*="--cat-d:9"] {
|
||||||
|
padding-left: 6px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.w-cats .yang-cats-children > .yang-cats-item > .yang-cats-link {
|
.w-cats .yang-cats-children > .yang-cats-item > .yang-cats-link {
|
||||||
@@ -2345,6 +2393,11 @@ button:focus {
|
|||||||
word-wrap: break-word;
|
word-wrap: break-word;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 更深层再浅一档颜色:三级往下继续淡化,层级更明确(不影响可读性) */
|
||||||
|
.w-cats .yang-cats-children .yang-cats-children > .yang-cats-item > .yang-cats-link {
|
||||||
|
color: #8f8f8f;
|
||||||
|
}
|
||||||
|
|
||||||
.w-cats .yang-cats-children > .yang-cats-item > .yang-cats-link:hover {
|
.w-cats .yang-cats-children > .yang-cats-item > .yang-cats-link:hover {
|
||||||
color: #00a2ff;
|
color: #00a2ff;
|
||||||
}
|
}
|
||||||
|
|||||||
Vendored
+1
-1
File diff suppressed because one or more lines are too long
+207
-94
@@ -1284,8 +1284,8 @@ class widget_categories extends WP_Widget
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* get_categories 返回的是平铺数组(按 orderby 排好),
|
/* get_categories 返回的是平铺数组(按 orderby 排好),
|
||||||
* 这里按 parent 归拢成树。不用 Walker,因为要输出 <details>,
|
* 这里按 parent 归拢成树。不用 Walker,因为要输出 <details> 面板,
|
||||||
* 而 Walker_Category 只认 <ul>/<li>。 */
|
* 而 Walker_Category 只认 <ul>/<li> 的固定形态。 */
|
||||||
$by_parent = array();
|
$by_parent = array();
|
||||||
foreach ($cats as $c) {
|
foreach ($cats as $c) {
|
||||||
$pid = (int) $c->parent;
|
$pid = (int) $c->parent;
|
||||||
@@ -1295,25 +1295,55 @@ class widget_categories extends WP_Widget
|
|||||||
$by_parent[$pid][] = $c;
|
$by_parent[$pid][] = $c;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 只保留「根(parent=0)→ 直接子级」两层。实测本站最深就是 2 层;
|
|
||||||
// 若将来有第三层,递归会把 <details> 套娃,侧栏观感反而更差。
|
|
||||||
$tree = array();
|
|
||||||
if (!isset($by_parent[0])) {
|
if (!isset($by_parent[0])) {
|
||||||
return $tree;
|
return array();
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($by_parent[0] as $root) {
|
/* 🔴 3.2.56 起改成**任意深度**递归(3.2.55 是写死两层)。
|
||||||
$rid = (int) $root->term_id;
|
*
|
||||||
$children = isset($by_parent[$rid]) ? $by_parent[$rid] : array();
|
* 用户的诉求是「把多级目录也放进去,注意缩进」。本站实测最深
|
||||||
$tree[] = array(
|
* 就 2 层(8 个一级 + 21 个二级,没有第三级),但"写死两层"
|
||||||
'cat' => $root,
|
* 的代码在将来有人加第三级时会**静默丢掉**那一层 —— 页面上
|
||||||
'children' => $children,
|
* 看不出错,只是分类凭空少了。这种"少显示了但没人报错"的
|
||||||
|
* 缺陷最难发现,所以这里一次做成递归。
|
||||||
|
*
|
||||||
|
* 🔴 递归必须带**已访问集合 + 深度保护**:
|
||||||
|
* · 数据库里 parent 指针理论上可以成环(手工改库、导入坏数据
|
||||||
|
* 都能造出来)。没有已访问集合的话,成环 ⇒ 无限递归 ⇒
|
||||||
|
* PHP 直接栈溢出白屏。侧栏挂件白屏会把整站都带下去。
|
||||||
|
* · 深度上限兜住其他意外(正常最多几级)。
|
||||||
|
* 两重保护都只用"跳过"处理,**不抛异常** —— 分类导航是
|
||||||
|
* 基础功能,宁可少显示一条也不能整站白屏。 */
|
||||||
|
$max_depth = 10;
|
||||||
|
|
||||||
|
$build = function ($parent_id, $depth, $seen) use (&$build, $by_parent, $max_depth) {
|
||||||
|
if ($depth > $max_depth || !isset($by_parent[$parent_id])) {
|
||||||
|
return array();
|
||||||
|
}
|
||||||
|
$out = array();
|
||||||
|
foreach ($by_parent[$parent_id] as $c) {
|
||||||
|
$cid = (int) $c->term_id;
|
||||||
|
// 成环或重复:跳过,不进入下一层
|
||||||
|
if (isset($seen[$cid])) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$seen[$cid] = true;
|
||||||
|
$out[] = array(
|
||||||
|
'cat' => $c,
|
||||||
|
'children' => $build($cid, $depth + 1, $seen),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
return $out;
|
||||||
|
};
|
||||||
|
|
||||||
/* 按文章数排序:在 PHP 里按「补过的 count」排,两边都排。
|
$tree = $build(0, 0, array());
|
||||||
|
|
||||||
|
/* 按文章数排序:在 PHP 里按「补过的 count」排,**每一层都排**。
|
||||||
* 用 usort + 显式 tie-break(count 相同时按名称),
|
* 用 usort + 显式 tie-break(count 相同时按名称),
|
||||||
* 否则相等项的先后顺序取决于 usort 的实现,每次请求可能不同。 */
|
* 否则相等项的先后顺序取决于 usort 的实现,每次请求可能不同。
|
||||||
|
*
|
||||||
|
* 🔴 这里必须递归到所有层 —— 3.2.55 只排了前两层,第三层往后
|
||||||
|
* 永远保持 get_categories 给的顺序,与「按文章数排」不一致。 */
|
||||||
if ($orderby === 'count') {
|
if ($orderby === 'count') {
|
||||||
$desc = ($order === 'DESC');
|
$desc = ($order === 'DESC');
|
||||||
|
|
||||||
@@ -1327,33 +1357,148 @@ class widget_categories extends WP_Widget
|
|||||||
return strnatcasecmp($a->name, $b->name);
|
return strnatcasecmp($a->name, $b->name);
|
||||||
};
|
};
|
||||||
|
|
||||||
usort($tree, function ($x, $y) use ($cmp) {
|
$sort_level = function (&$nodes) use (&$sort_level, $cmp) {
|
||||||
|
usort($nodes, function ($x, $y) use ($cmp) {
|
||||||
return $cmp($x['cat'], $y['cat']);
|
return $cmp($x['cat'], $y['cat']);
|
||||||
});
|
});
|
||||||
|
foreach ($nodes as $i => $n) {
|
||||||
|
if (!empty($n['children'])) {
|
||||||
|
$sort_level($nodes[$i]['children']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
foreach ($tree as $i => $node) {
|
$sort_level($tree);
|
||||||
if (count($node['children']) > 1) {
|
|
||||||
usort($tree[$i]['children'], $cmp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $tree;
|
return $tree;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 在树里按 term_id 找分类名(任意深度)。
|
||||||
|
*
|
||||||
|
* 🔴 单独抽出来,是为了让「触发条文案」和「面板渲染」用**同一套**
|
||||||
|
* 遍历逻辑。3.2.55 那版是两段各自硬编码两层的循环 —— 一旦树的
|
||||||
|
* 层数变了,两处必须同时改,漏一处就会「面板里有、触发条上找不到」。
|
||||||
|
*
|
||||||
|
* 找不到返回空串(调用方据此显示占位文案「选择分类」)。
|
||||||
|
*
|
||||||
|
* @param array $tree get_tree() 的返回值
|
||||||
|
* @param int $cat_id
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
private function find_name(array $tree, $cat_id)
|
||||||
|
{
|
||||||
|
foreach ($tree as $node) {
|
||||||
|
if ((int) $node['cat']->term_id === (int) $cat_id) {
|
||||||
|
return (string) $node['cat']->name;
|
||||||
|
}
|
||||||
|
if (!empty($node['children'])) {
|
||||||
|
$got = $this->find_name($node['children'], $cat_id);
|
||||||
|
if ($got !== '') {
|
||||||
|
return $got;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 递归渲染一层分类(任意深度)。
|
||||||
|
*
|
||||||
|
* 每层的 DOM 完全一样:
|
||||||
|
*
|
||||||
|
* <li class="yang-cats-item" style="--cat-d: N">
|
||||||
|
* <a class="yang-cats-link">名字</a>
|
||||||
|
* <span class="yang-cats-count">N</span>
|
||||||
|
* <ul class="yang-cats-children"> …下一层… </ul>
|
||||||
|
* </li>
|
||||||
|
*
|
||||||
|
* 🔴 下一层的 `<ul>` 必须放在**本层 li 里面**,不能放在 li 外面当兄弟:
|
||||||
|
* HTML 里 `<ul>` 的直接子元素只能是 `<li>`,写成
|
||||||
|
* `<ul><li/><ul/><li/></ul>` 是非法结构,浏览器容错行为不可依赖。
|
||||||
|
*
|
||||||
|
* 🔴 缩进靠**逐层累加的左内边距**:
|
||||||
|
* li 是 `display:flex; flex-wrap:wrap`
|
||||||
|
* 下一层 ul 用 `flex: 0 0 100%` 独占一行(不进 flex 主轴)
|
||||||
|
* ⇒ 嵌套 ul 落在父级 li 的**内容盒**内,天然右边界一致
|
||||||
|
* ⇒ 所以每层 li 的 padding-left 相加就是缩进,且**数字右沿
|
||||||
|
* 始终对齐到面板右侧同一列**(数字要竖着比大小,不能错开)
|
||||||
|
*
|
||||||
|
* 3.2.55 只做两层,靠 `<ul padding-left>` 做缩进,导致子级数字比
|
||||||
|
* 父级多缩进 12px(那次修的是把子级 li 的 padding-right 归零)。
|
||||||
|
* 改成"逐层 li padding-left、padding-right 只在顶层给"之后,
|
||||||
|
* 这个对齐关系对**任意层数**都成立。
|
||||||
|
*
|
||||||
|
* @param array $nodes 本层节点
|
||||||
|
* @param int $current_id 当前分类页的 term_id(0 = 不在分类页)
|
||||||
|
* @param array $ancestors 当前分类的祖先 id 链
|
||||||
|
* @param bool $show_count 是否显示文章数
|
||||||
|
* @param int $depth 当前层深度(0 = 顶级)
|
||||||
|
*/
|
||||||
|
private function render_level(array $nodes, $current_id, array $ancestors, $show_count, $depth = 0)
|
||||||
|
{
|
||||||
|
if (count($nodes) === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
echo $depth === 0
|
||||||
|
? '<ul class="yang-cats-list">'
|
||||||
|
: '<ul class="yang-cats-children">';
|
||||||
|
|
||||||
|
foreach ($nodes as $node) {
|
||||||
|
$cat = $node['cat'];
|
||||||
|
$cid = (int) $cat->term_id;
|
||||||
|
$kids = isset($node['children']) ? $node['children'] : array();
|
||||||
|
|
||||||
|
$cls = 'yang-cats-item';
|
||||||
|
if ($current_id === $cid) {
|
||||||
|
$cls .= ' current-cat';
|
||||||
|
} elseif (in_array($cid, $ancestors, true)) {
|
||||||
|
/* 当前在看这个父级底下的子分类 —— 父级挂 current-cat-parent,
|
||||||
|
* 与核心 Walker_Category 的类名保持一致,便于写样式。
|
||||||
|
* 这条要**对每一层都生效**(3.2.55 只对第一层生效)。 */
|
||||||
|
$cls .= ' current-cat-parent';
|
||||||
|
}
|
||||||
|
if (count($kids) > 0) {
|
||||||
|
$cls .= ' has-children';
|
||||||
|
}
|
||||||
|
|
||||||
|
echo '<li class="' . esc_attr($cls) . '" style="--cat-d:' . $depth . '">';
|
||||||
|
echo '<a class="yang-cats-link" href="' . esc_url(get_category_link($cid)) . '">'
|
||||||
|
. $this->name_html($cat->name) . '</a>';
|
||||||
|
if ($show_count) {
|
||||||
|
echo '<span class="yang-cats-count">' . (int) $cat->count . '</span>';
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 下一层直接接在 li 内部(合法结构),由 CSS 的 flex-wrap 让它独占一行 */
|
||||||
|
if (count($kids) > 0) {
|
||||||
|
$this->render_level($kids, $current_id, $ancestors, $show_count, $depth + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
echo '</li>';
|
||||||
|
}
|
||||||
|
|
||||||
|
echo '</ul>';
|
||||||
|
}
|
||||||
|
|
||||||
public function widget($args, $instance)
|
public function widget($args, $instance)
|
||||||
{
|
{
|
||||||
$show_count = $this->pick($instance, 'count', true);
|
$show_count = $this->pick($instance, 'count', true);
|
||||||
$hide_empty = $this->pick($instance, 'hide_empty', true);
|
$hide_empty = $this->pick($instance, 'hide_empty', true);
|
||||||
/* 🔴 children 默认值 3.2.55 改成 **false**(3.2.54 是 true)。
|
/* 🔴 children 默认值 3.2.56 改回 **true**(3.2.55 是 false)。
|
||||||
*
|
*
|
||||||
* 用户的诉求原话是「点击后把所有**一级**分类拉出来」—— 默认就该
|
* 3.2.55 时用户的诉求是「点击后把所有**一级**分类拉出来」,
|
||||||
* 只有一级。线上那个实例 `categories-3` 是核心老配置,压根没有
|
* 所以默认只列一级。2026-10-27 追加要求:「把多级目录也放进去,
|
||||||
* children 这个键 ⇒ 走 fallback ⇒ 改默认值就等于改线上呈现,
|
* 现在只显示第一级,把其他的也放进去,注意缩进」⇒ 默认改成
|
||||||
* 不需要用户去后台勾一下,也不用动数据库。
|
* 列出**所有层级**(递归渲染,缩进表达层级)。
|
||||||
*
|
*
|
||||||
* 想连子级一起看的人,在后台勾上即可(update() 会存成 1)。 */
|
* 线上那个实例 `categories-3` 是核心老配置,压根没有 children
|
||||||
$show_children = $this->pick($instance, 'children', false);
|
* 这个键 ⇒ 走 fallback ⇒ **改兜底值就等于改线上呈现**,用户
|
||||||
|
* 不用进后台勾一下,也不用动数据库。这是本挂件最省事的杠杆。
|
||||||
|
*
|
||||||
|
* 仍然保留开关:侧栏分类特别多时,可以在后台关掉只留一级。 */
|
||||||
|
$show_children = $this->pick($instance, 'children', true);
|
||||||
$orderby = $this->pick($instance, 'orderby', 'name');
|
$orderby = $this->pick($instance, 'orderby', 'name');
|
||||||
$order = $this->pick($instance, 'order', 'ASC');
|
$order = $this->pick($instance, 'order', 'ASC');
|
||||||
|
|
||||||
@@ -1410,18 +1555,7 @@ class widget_categories extends WP_Widget
|
|||||||
* 所以不必再往祖先链上找。 */
|
* 所以不必再往祖先链上找。 */
|
||||||
$current_name = '';
|
$current_name = '';
|
||||||
if ($current_id > 0) {
|
if ($current_id > 0) {
|
||||||
foreach ($tree as $node) {
|
$current_name = $this->find_name($tree, $current_id);
|
||||||
if ((int) $node['cat']->term_id === $current_id) {
|
|
||||||
$current_name = (string) $node['cat']->name;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
foreach ($node['children'] as $kid) {
|
|
||||||
if ((int) $kid->term_id === $current_id) {
|
|
||||||
$current_name = (string) $kid->name;
|
|
||||||
break 2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 面板 DOM id:一页上可能有多个实例(虽然实际很少),必须唯一,
|
/* 面板 DOM id:一页上可能有多个实例(虽然实际很少),必须唯一,
|
||||||
@@ -1450,63 +1584,42 @@ class widget_categories extends WP_Widget
|
|||||||
echo '</summary>';
|
echo '</summary>';
|
||||||
|
|
||||||
echo '<div class="yang-cats-panel" id="' . esc_attr($panel_id) . '">';
|
echo '<div class="yang-cats-panel" id="' . esc_attr($panel_id) . '">';
|
||||||
echo '<ul class="yang-cats-list">';
|
|
||||||
|
|
||||||
foreach ($tree as $node) {
|
/* 🔴 3.2.56:子分类从「两层平铺」改成**递归渲染所有层级**。
|
||||||
$root = $node['cat'];
|
|
||||||
$rid = (int) $root->term_id;
|
|
||||||
$kids = $node['children'];
|
|
||||||
$has_kids = ($show_children && count($kids) > 0);
|
|
||||||
|
|
||||||
$root_cls = 'yang-cats-item';
|
|
||||||
if ($has_kids) {
|
|
||||||
$root_cls .= ' has-children';
|
|
||||||
}
|
|
||||||
if ($current_id === $rid) {
|
|
||||||
$root_cls .= ' current-cat';
|
|
||||||
} elseif (in_array($rid, $current_ancestors, true)) {
|
|
||||||
/* 当前在看这个父级底下的子分类 —— 父级挂 current-cat-parent,
|
|
||||||
* 与核心 Walker_Category 的类名保持一致,便于写样式。 */
|
|
||||||
$root_cls .= ' current-cat-parent';
|
|
||||||
}
|
|
||||||
|
|
||||||
echo '<li class="' . esc_attr($root_cls) . '">';
|
|
||||||
echo '<a class="yang-cats-link" href="' . esc_url(get_category_link($rid)) . '">'
|
|
||||||
. $this->name_html($root->name) . '</a>';
|
|
||||||
if ($show_count) {
|
|
||||||
echo '<span class="yang-cats-count">' . (int) $root->count . '</span>';
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 子分类:只有用户显式勾了「显示子分类」才输出。
|
|
||||||
*
|
*
|
||||||
* 🔴 这里**不再用 <details> 嵌套**(3.2.54 是那样)。原因:
|
* 用户 2026-10-27 的要求:「把多级目录也放进去,现在只显示第一级,
|
||||||
* 面板本身就是浮层,展开状态只由触发条一个开关管;
|
* 把其他的也放进去,注意缩进」。
|
||||||
* 再套一层折叠,用户点开面板后仍要再点一次才能看见子级,
|
*
|
||||||
* 「点击后把所有的一级分类拉出来」这个诉求就没满足。
|
* ⇒ 面板里现在一次列全:一级 → 二级 → 三级(有几层列几层),
|
||||||
* 子级直接平铺在父级下面、缩进显示 —— 一目了然,少一次点击。 */
|
* 点开一次就能看到全部,不用逐层点。
|
||||||
if ($has_kids) {
|
*
|
||||||
echo '<ul class="yang-cats-children">';
|
* 🔴 缩进**不是**靠 `--cat-d` 变量算的(那样每层都要写一条
|
||||||
foreach ($kids as $kid) {
|
* 偏移量规则,层数一变就得改 CSS)。缩进靠**嵌套 + 逐层
|
||||||
$kid_id = (int) $kid->term_id;
|
* padding-left** 自然累加:`.yang-cats-children` 用
|
||||||
$kid_cls = 'yang-cats-item';
|
* `flex: 0 0 100%` 独占一行、嵌在父级 li 的内容盒里,
|
||||||
if ($current_id === $kid_id) {
|
* 所以每层 li 的 padding-left 相加就是缩进,右边界还一致。
|
||||||
$kid_cls .= ' current-cat';
|
* `--cat-d` 只用来做两件事:① 标记真实深度供第 4 层起
|
||||||
|
* 缩进收敛(`[style*="--cat-d:3"]` 起);② 给测试读。
|
||||||
|
* **它不参与算缩进**,写错了也不会导致布局错位。
|
||||||
|
*
|
||||||
|
* 🔴 仍然保留 `children` 开关(默认已改回 **true**):
|
||||||
|
* 有人侧栏分类多,全列出来面板太长要滚很久,这时可以关掉
|
||||||
|
* 只留一级。关掉时不是"少一层",而是**只列一级**。
|
||||||
|
*
|
||||||
|
* 🔴 关掉时的实现不是另写一份循环,而是把每个节点的 children
|
||||||
|
* 清空后交给同一个渲染函数 —— 两份循环必然会漂移(3.2.55
|
||||||
|
* 就是两段各自硬编码两层),一处改了另一处忘改就出怪现象。 */
|
||||||
|
if ($show_children) {
|
||||||
|
$this->render_level($tree, $current_id, $current_ancestors, $show_count);
|
||||||
|
} else {
|
||||||
|
$roots = array();
|
||||||
|
foreach ($tree as $node) {
|
||||||
|
$node['children'] = array();
|
||||||
|
$roots[] = $node;
|
||||||
}
|
}
|
||||||
echo '<li class="' . esc_attr($kid_cls) . '">';
|
$this->render_level($roots, $current_id, $current_ancestors, $show_count);
|
||||||
echo '<a class="yang-cats-link" href="' . esc_url(get_category_link($kid_id)) . '">'
|
|
||||||
. $this->name_html($kid->name) . '</a>';
|
|
||||||
if ($show_count) {
|
|
||||||
echo '<span class="yang-cats-count">' . (int) $kid->count . '</span>';
|
|
||||||
}
|
|
||||||
echo '</li>';
|
|
||||||
}
|
|
||||||
echo '</ul>';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
echo '</li>';
|
|
||||||
}
|
|
||||||
|
|
||||||
echo '</ul>';
|
|
||||||
echo '</div>';
|
echo '</div>';
|
||||||
echo '</details>';
|
echo '</details>';
|
||||||
echo '</div>';
|
echo '</div>';
|
||||||
@@ -1594,7 +1707,7 @@ class widget_categories extends WP_Widget
|
|||||||
$show_count = $this->pick($instance, 'count', true);
|
$show_count = $this->pick($instance, 'count', true);
|
||||||
$hide_empty = $this->pick($instance, 'hide_empty', true);
|
$hide_empty = $this->pick($instance, 'hide_empty', true);
|
||||||
// 与 widget() 保持同一默认值(理由见 widget() 里的注释)
|
// 与 widget() 保持同一默认值(理由见 widget() 里的注释)
|
||||||
$show_children = $this->pick($instance, 'children', false);
|
$show_children = $this->pick($instance, 'children', true);
|
||||||
$orderby = $this->pick($instance, 'orderby', 'name');
|
$orderby = $this->pick($instance, 'orderby', 'name');
|
||||||
$order = $this->pick($instance, 'order', 'ASC');
|
$order = $this->pick($instance, 'order', 'ASC');
|
||||||
if ($orderby !== 'count') {
|
if ($orderby !== 'count') {
|
||||||
@@ -1613,8 +1726,8 @@ class widget_categories extends WP_Widget
|
|||||||
|
|
||||||
<p>
|
<p>
|
||||||
<input class="checkbox" type="checkbox" id="<?php echo esc_attr($this->get_field_id('children')); ?>" name="<?php echo esc_attr($this->get_field_name('children')); ?>" <?php checked($show_children); ?>>
|
<input class="checkbox" type="checkbox" id="<?php echo esc_attr($this->get_field_id('children')); ?>" name="<?php echo esc_attr($this->get_field_name('children')); ?>" <?php checked($show_children); ?>>
|
||||||
<label for="<?php echo esc_attr($this->get_field_id('children')); ?>"><?php _e('展开时同时列出子分类', 'kratos'); ?></label>
|
<label for="<?php echo esc_attr($this->get_field_id('children')); ?>"><?php _e('列出子分类(含更多层级)', 'kratos'); ?></label>
|
||||||
<span class="description"><?php _e('默认只列一级分类。勾上后,有子分类的父级下面会缩进列出它的子分类。', 'kratos'); ?></span>
|
<span class="description"><?php _e('默认列出全部层级,下级缩进显示。分类特别多、面板太长时,可以关掉只留一级分类。', 'kratos'); ?></span>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
Theme Name: Kratos_Yang
|
Theme Name: Kratos_Yang
|
||||||
Text Domain: kratos_Yang
|
Text Domain: kratos_Yang
|
||||||
Version: 3.2.55
|
Version: 3.2.56
|
||||||
Requires PHP: 7.0
|
Requires PHP: 7.0
|
||||||
Description: 这是一个Kratos主题的分支版本,用来增加一些定制化功能。
|
Description: 这是一个Kratos主题的分支版本,用来增加一些定制化功能。
|
||||||
Tags: 博客, 双栏, 响应式, 自定义背景, 自定义颜色, 自定义图标, 自定义菜单, 特色图像, 收录优化, 邮件中心, 主题选项, 小工具, 文章置顶, 无障碍友好
|
Tags: 博客, 双栏, 响应式, 自定义背景, 自定义颜色, 自定义图标, 自定义菜单, 特色图像, 收录优化, 邮件中心, 主题选项, 小工具, 文章置顶, 无障碍友好
|
||||||
|
|||||||
Reference in New Issue
Block a user