后台「小工具」找不到可拖动的挂件:界面被换成区块编辑器(3.2.53 已修) #23

Closed
opened 2026-10-27 00:52:52 +00:00 by laoyang · 2 comments
Owner

来源

用户 2026-10-27 在升级 3.2.52 后,进后台准备把旧的插件版「最近评论」换成主题自带的,反馈:

我应该怎么拖动?现在我在添加小工具那个地方,都已经找不到我们这个主题自带的这些小工具在什么地方了,它好像全部是区块。

线上实测(yangyq.net,WP 7.1.3,PHP 8.5.12,主题 3.2.51)

用只读脚本 wp-load.php 逐个量,不是猜:

wp_use_widgets_block_editor(): true
get_theme_support('widgets-block-editor'): true

⇒ 后台「外观 → 小工具」走的是 wp-admin/widgets-form-blocks.php(区块编辑器),
不再是老式的可拖放面板。wp-admin/widgets.php 第 38 行就是这么分流的:

if ( wp_use_widgets_block_editor() ) {
    require ABSPATH . 'wp-admin/widgets-form-blocks.php';
} else {
    require ABSPATH . 'wp-admin/widgets-form.php';
}

更严重的一层:4 个挂件的显示名是空的

widget_about   id_base='about'    name=false  option_name=widget_about
widget_ad      id_base='ad'       name=false  option_name=widget_ad
widget_posts   id_base='posts'    name=false  option_name=widget_posts
widget_tags    id_base='tags'     name=false  option_name=widget_tags

源码(inc/theme-widgets.php)里四个挂件都这么写:

$widget_ops = array(
    'name' => __('个人简介', 'kratos'),          // ← 写在 $widget_ops 里
    'description' => __('可跳转后台的个人简介展示工具', 'kratos'),
);
parent::__construct(false, false, $widget_ops);   // ← 第二参 $name 传的是 false

而 WP_Widget::__construct 对 $name 不做兜底:

$this->id_base     = $id_base;
$this->name        = $name;      // 直接赋值,false 就是 false
$this->widget_options = wp_parse_args($widget_options, array(...));

wp_parse_args 只补 classname / customize_selective_refresh,不补 name。
所以 $widget_ops['name'] 根本没人读,最终 $widget->name 是 false。

这两个问题叠加的后果

区块编辑器的插入器按挂件名列条目与搜索。名字是空的 ⇒ 那 4 个挂件在列表里是
几条没有文字的空行,按「个人简介」「文章聚合」「标签聚合」「图片广告」都搜不到。

本版新加的 widget_recent_comments 是对的写法,所以它是唯一能正常显示名字的那个:

parent::__construct('yang_recent_comments', __('最近评论', 'kratos'), $widget_ops);

需求

一、给 4 个挂件补上显示名(必须)

  • widget_about → 「个人简介」
  • widget_ad → 「图片广告」
  • widget_posts → 「文章聚合」
  • widget_tags → 「标签聚合」

同时核对 description 是否被区块界面读取,没有就一并修。

必须保留 $id_base 不变 —— 已实测它们分别是 about / ad / posts / tags,
与库里现存的 option 名(widget_about 等)一致,线上已有 3 个实例在用
(widget_about 3 条、widget_posts 2 条)。改名字不能把用户的既有配置弄丢。
做法:把 false 换成显式 id_base,或改用 parent::__construct($id_base, $name, $ops)。

二、后台挂件界面的选择(需要确认)

两条路,各有代价,需要用户拍板:

A. 关掉区块编辑器,回到传统可拖放面板

add_filter('use_widgets_block_editor', '__return_false');
  • 好的地方:就是用户熟悉的"左边拖到右边";主题自己的挂件后台样式(3.2.51 做的媒体框、
    缩略图预览)在老面板里是验证过的。
  • 代价:WP 官方长期方向是区块,未来大版本可能彻底移除老面板。

B. 保留区块编辑器,靠补名字解决"找不到"

  • 好的地方:跟着官方走,长期不会失效。
  • 代价:需要用户接受"点 + 号插入"的操作方式,不是拖放。

⚠️ 注意:在老面板里也有同样的空名问题 —— 所以第一项必须先修,它跟选 A 还是 B 无关。

三、验收标准

  1. 后台「小工具」能看到 4 个主题挂件,名字正确、能按名字搜到
  2. 已存在的挂件实例一个都不能丢(widget_about 3 条、widget_posts 2 条仍在,前台渲染不变)
  3. 新挂件「最近评论」和这 4 个老挂件在同一种界面下都能正常插入/拖动
  4. 前台样式不受影响(几何回归 50/0 仍绿)

附:与 #22 的关系

与 #22(新增「最近评论」挂件)不重叠:#22 只加了新挂件,本单修的是"老挂件名字为空

  • 后台界面形态"。但 #22 里"换掉插件版"那一步依赖本单,因为用户现在找不到挂件就没法换。

为什么单独建单

#22 只新增了挂件;本单是 4 个老挂件显示名为空 + 后台界面被换成区块,可独立验收

## 来源 用户 2026-10-27 在升级 3.2.52 后,进后台准备把旧的插件版「最近评论」换成主题自带的,反馈: > 我应该怎么拖动?现在我在添加小工具那个地方,都已经找不到我们这个主题自带的这些小工具在什么地方了,它好像全部是区块。 ## 线上实测(yangyq.net,WP 7.1.3,PHP 8.5.12,主题 3.2.51) 用只读脚本 `wp-load.php` 逐个量,不是猜: ``` wp_use_widgets_block_editor(): true get_theme_support('widgets-block-editor'): true ``` ⇒ 后台「外观 → 小工具」走的是 **`wp-admin/widgets-form-blocks.php`(区块编辑器)**, 不再是老式的可拖放面板。`wp-admin/widgets.php` 第 38 行就是这么分流的: ```php if ( wp_use_widgets_block_editor() ) { require ABSPATH . 'wp-admin/widgets-form-blocks.php'; } else { require ABSPATH . 'wp-admin/widgets-form.php'; } ``` ### 更严重的一层:4 个挂件的显示名是空的 ``` widget_about id_base='about' name=false option_name=widget_about widget_ad id_base='ad' name=false option_name=widget_ad widget_posts id_base='posts' name=false option_name=widget_posts widget_tags id_base='tags' name=false option_name=widget_tags ``` 源码(`inc/theme-widgets.php`)里四个挂件都这么写: ```php $widget_ops = array( 'name' => __('个人简介', 'kratos'), // ← 写在 $widget_ops 里 'description' => __('可跳转后台的个人简介展示工具', 'kratos'), ); parent::__construct(false, false, $widget_ops); // ← 第二参 $name 传的是 false ``` 而 `WP_Widget::__construct` 对 `$name` **不做兜底**: ```php $this->id_base = $id_base; $this->name = $name; // 直接赋值,false 就是 false $this->widget_options = wp_parse_args($widget_options, array(...)); ``` `wp_parse_args` 只补 `classname` / `customize_selective_refresh`,**不补 `name`**。 所以 `$widget_ops['name']` 根本没人读,最终 `$widget->name` 是 `false`。 ### 这两个问题叠加的后果 区块编辑器的插入器按**挂件名**列条目与搜索。名字是空的 ⇒ 那 4 个挂件在列表里是 **几条没有文字的空行**,按「个人简介」「文章聚合」「标签聚合」「图片广告」都搜不到。 本版新加的 `widget_recent_comments` 是对的写法,所以它是唯一能正常显示名字的那个: ```php parent::__construct('yang_recent_comments', __('最近评论', 'kratos'), $widget_ops); ``` ## 需求 ### 一、给 4 个挂件补上显示名(必须) - `widget_about` → 「个人简介」 - `widget_ad` → 「图片广告」 - `widget_posts` → 「文章聚合」 - `widget_tags` → 「标签聚合」 同时核对 `description` 是否被区块界面读取,没有就一并修。 **必须保留 `$id_base` 不变** —— 已实测它们分别是 `about` / `ad` / `posts` / `tags`, 与库里现存的 option 名(`widget_about` 等)一致,线上已有 3 个实例在用 (`widget_about` 3 条、`widget_posts` 2 条)。**改名字不能把用户的既有配置弄丢。** 做法:把 `false` 换成显式 id_base,或改用 `parent::__construct($id_base, $name, $ops)`。 ### 二、后台挂件界面的选择(需要确认) 两条路,各有代价,需要用户拍板: **A. 关掉区块编辑器,回到传统可拖放面板** ```php add_filter('use_widgets_block_editor', '__return_false'); ``` - 好的地方:就是用户熟悉的"左边拖到右边";主题自己的挂件后台样式(3.2.51 做的媒体框、 缩略图预览)在老面板里是验证过的。 - 代价:WP 官方长期方向是区块,未来大版本可能彻底移除老面板。 **B. 保留区块编辑器,靠补名字解决"找不到"** - 好的地方:跟着官方走,长期不会失效。 - 代价:需要用户接受"点 + 号插入"的操作方式,不是拖放。 ⚠️ 注意:**在老面板里也有同样的空名问题** —— 所以第一项必须先修,它跟选 A 还是 B 无关。 ### 三、验收标准 1. 后台「小工具」能看到 4 个主题挂件,名字正确、能按名字搜到 2. 已存在的挂件实例**一个都不能丢**(`widget_about` 3 条、`widget_posts` 2 条仍在,前台渲染不变) 3. 新挂件「最近评论」和这 4 个老挂件在同一种界面下都能正常插入/拖动 4. 前台样式不受影响(几何回归 50/0 仍绿) ## 附:与 #22 的关系 与 #22(新增「最近评论」挂件)**不重叠**:#22 只加了新挂件,本单修的是"老挂件名字为空 + 后台界面形态"。但 #22 里"换掉插件版"那一步依赖本单,因为用户现在找不到挂件就没法换。 --- ### 为什么单独建单 #22 只新增了挂件;本单是 4 个老挂件显示名为空 + 后台界面被换成区块,可独立验收
Author
Owner

3.2.53 已发布到 theme-update/,等你在后台点升级确认。

已做的事

后台「外观 → 小工具」恢复成传统拖放面板(左右两栏、可拖动)。用了两道开关互为备份:

  • add_filter('use_widgets_block_editor', '__return_false')
  • remove_theme_support('widgets-block-editor'),挂在 after_setup_theme 优先级 20

第二道必须挂在那个钩子上:核心的 wp_setup_widgets_block_editor() 挂在同一个钩子的优先级 1 上默认 add 这条 support,写早了会因为"还没 add 就 remove"而静默失败。

一个必须说清楚的纠正

我在这次排查里下过一个错误结论,并且已经把它写进了代码注释和测试判据里,现在全部改掉了。

错误结论是:这 4 个挂件后台名字是空的,所以用户找不到。

实测结果相反。原写法 parent::__construct(false, false, $widget_ops) 里 $widget->name 确实是 false,但后台列表与搜索读的不是它,而是 $wp_registered_widgets[<id>]['name']。这条链是:

_register_one()
  → wp_register_sidebar_widget($id, $this->name, ..., $this->widget_options)
  → $widget = array('name' => $name, ...)          // 此时是 false
  → $widget = array_merge($widget, $options)       // $options 里的 'name' 覆盖掉 false

老代码实测:$widget->name = false,$wp_registered_widgets['ad-1']['name'] = '图片广告'。

所以挂件名字从来没空过,用户找不到挂件与名字毫无关系,纯粹是区块编辑器没有拖放动作。

我之所以被骗,是因为那条判据查的是 $widget->name —— 一个用户根本看不到的内部属性。它在老代码上红、在新代码上绿,看着很有"牙齿",实际上产品侧从来没坏过。这是典型的「判据选错了靶子」。

仍然改了构造函数,但性质不同

4 个挂件的名字改成显式走第 2 参。这是可读性清理(不再依赖 array_merge 那层隐式覆盖),不是修用户可见缺陷。判据也拆成了两层:一层查注册表(用户可见,老代码也全绿),一层查构造实参(代码质量,老代码才红)。

id_base 全部保持原值(ad/about/tags/posts),已有挂件实例一个都不会丢。

验证

  • 真实 WP 7.1.3 加载待发布包(临时主题副本,不碰线上主题目录):页面级 28 条 + 元数据 50 条判据全绿
  • 同一套判据跑老代码:只有区块开关相关失败,名字类判据全部通过 —— 这条对照本身就是上面那个纠正的证据
  • 9 组反证全部真红,其中 R1「只去掉 use_widgets_block_editor 一道」确认仍然全绿 —— 这是设计的冗余,不是判据没牙齿
  • 96 个 PHP 文件全量 lint 通过
  • 发布脚本中途被自己的判据拦下两次(一次是把 register_sidebar 的 'name' 误判成挂件名重复配置,一次是 .name. 正则通配符把 'classname' 吃掉了),都修干净才放行

状态

  • update.json → 3.2.53,HTTP 独立复核(md5 / 包完整性 / readme 首行)全过
  • 服务器主题目录仍是 3.2.52,未被覆盖(红线守住)
  • git 75848f2,已推 baa1d16..75848f2

工单先不关,等你升级后在后台看一眼:应该是左右两栏、能拖动的界面。如果还是区块界面,可能是别的插件用同一个过滤器强行打开了它,告诉我我再查。

3.2.53 已发布到 `theme-update/`,等你在后台点升级确认。 ## 已做的事 后台「外观 → 小工具」恢复成传统拖放面板(左右两栏、可拖动)。用了两道开关互为备份: - `add_filter('use_widgets_block_editor', '__return_false')` - `remove_theme_support('widgets-block-editor')`,挂在 `after_setup_theme` 优先级 20 第二道必须挂在那个钩子上:核心的 `wp_setup_widgets_block_editor()` 挂在同一个钩子的**优先级 1** 上默认 add 这条 support,写早了会因为"还没 add 就 remove"而静默失败。 ## 一个必须说清楚的纠正 我在这次排查里下过一个**错误结论**,并且已经把它写进了代码注释和测试判据里,现在全部改掉了。 错误结论是:这 4 个挂件后台名字是空的,所以用户找不到。 实测结果相反。原写法 `parent::__construct(false, false, $widget_ops)` 里 `$widget->name` 确实是 `false`,但后台列表与搜索读的**不是它**,而是 `$wp_registered_widgets[<id>]['name']`。这条链是: ``` _register_one() → wp_register_sidebar_widget($id, $this->name, ..., $this->widget_options) → $widget = array('name' => $name, ...) // 此时是 false → $widget = array_merge($widget, $options) // $options 里的 'name' 覆盖掉 false ``` 老代码实测:`$widget->name` = `false`,`$wp_registered_widgets['ad-1']['name']` = `'图片广告'`。 **所以挂件名字从来没空过,用户找不到挂件与名字毫无关系,纯粹是区块编辑器没有拖放动作。** 我之所以被骗,是因为那条判据查的是 `$widget->name` —— 一个用户根本看不到的内部属性。它在老代码上红、在新代码上绿,看着很有"牙齿",实际上产品侧从来没坏过。这是典型的「判据选错了靶子」。 ## 仍然改了构造函数,但性质不同 4 个挂件的名字改成显式走第 2 参。这是**可读性清理**(不再依赖 `array_merge` 那层隐式覆盖),不是修用户可见缺陷。判据也拆成了两层:一层查注册表(用户可见,老代码也全绿),一层查构造实参(代码质量,老代码才红)。 `id_base` 全部保持原值(`ad`/`about`/`tags`/`posts`),已有挂件实例一个都不会丢。 ## 验证 - 真实 WP 7.1.3 加载**待发布包**(临时主题副本,不碰线上主题目录):页面级 28 条 + 元数据 50 条判据全绿 - 同一套判据跑老代码:只有区块开关相关失败,名字类判据全部通过 —— 这条对照本身就是上面那个纠正的证据 - 9 组反证全部真红,其中 R1「只去掉 `use_widgets_block_editor` 一道」确认**仍然全绿** —— 这是设计的冗余,不是判据没牙齿 - 96 个 PHP 文件全量 lint 通过 - 发布脚本中途被自己的判据拦下两次(一次是把 `register_sidebar` 的 `'name'` 误判成挂件名重复配置,一次是 `.name.` 正则通配符把 `'classname'` 吃掉了),都修干净才放行 ## 状态 - `update.json` → 3.2.53,HTTP 独立复核(md5 / 包完整性 / readme 首行)全过 - **服务器主题目录仍是 3.2.52,未被覆盖**(红线守住) - git `75848f2`,已推 `baa1d16..75848f2` **工单先不关**,等你升级后在后台看一眼:应该是左右两栏、能拖动的界面。如果还是区块界面,可能是别的插件用同一个过滤器强行打开了它,告诉我我再查。
laoyang changed title from 后台「小工具」找不到主题自带的挂件:4 个挂件显示名为空 + 界面被换成区块编辑器 to 后台「小工具」找不到可拖动的挂件:界面被换成区块编辑器(3.2.53 已修) 2026-10-27 01:23:28 +00:00
Author
Owner

按用户确认收尾,交付见上条发布评论。

交付版本:3.2.53(关掉区块小工具编辑器,恢复传统拖放面板)

用户已验收,关闭本单。

按用户确认收尾,交付见上条发布评论。 交付版本:3.2.53(关掉区块小工具编辑器,恢复传统拖放面板) 用户已验收,关闭本单。
Sign in to join this conversation.
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: laoyang/wordpress-kratos-yang#23