把自定义样式从主题目录搬到主题选项,升级不再丢

原来主题里有个 custom/ 目录(custom.css / custom.js / custom.php),
是给用户随手加样式的入口。问题是它位于主题目录内,而 WordPress 升级
主题的做法是把整个主题目录删掉再解压(class-theme-upgrader.php 里
clear_destination = true,随后 delete_old_theme() 递归删除),
所以每次升级这些文件都会丢。custom.php 还会被 require,
等于在主题里留了一个执行任意 PHP 的口子。

改成后台选项:
- 主题选项新增「自定义代码」组,含自定义 CSS / 自定义 JS 两个输入框
- 内容存在数据库的 kratos 选项里,与主题文件解耦,升级、重装都不影响
- 分别在主题样式和主题脚本之后加载,优先级最高

为此新增了 code 字段类型,没有复用 textarea:textarea 的 sanitizer
走 wp_kses(),CSS 的子选择器 > 和 JS 的 < 会被当成 HTML 标签剥掉,
样式会静默失效。code 类型只去掉 PHP 标签、打断 </style> 和 </script>,
其余原样保留。渲染时也不走公共的 stripslashes —— options.php 已经
wp_unslash 过,再剥一层会把 CSS 的 \f101、JS 的 \n 啃坏。

自定义 CSS 的默认值就是原来 custom.css 的内容,逐字节一致(354 字节),
所以升级瞬间站点外观没有任何变化。清空输入框保存即可彻底去掉。

验证:真实 WP 7.1.3 / PHP 8.5.12 环境 20 条断言全过(含 DB 往返、
子选择器 / 反斜杠保真、危险内容过滤),生产选项指纹前后一致;
反向注入「默认值改空」能立刻被抓到。
This commit is contained in:
2026-10-23 10:35:56 +08:00
parent 8a55457210
commit eaabc7717f
11 changed files with 180 additions and 54 deletions
+20 -7
View File
@@ -86,7 +86,7 @@ theme-update/readme.html # 「详情」页,可省
**先改 `style.css` 里的 `Version`,再打包**,否则 WordPress 认为没有新版本,不会提示升级。
1. 改 `style.css` 的 `Version`(例如 3.2.0 → 3.3.0)
1. 改 `style.css` 的 `Version`(例如 3.2.2 → 3.3.0)
2. 打包:`zip -r kratos_yang.zip kratos_yang -x "*.DS_Store" "*/.git/*"`
3. 传 `kratos_yang.zip` 到 `theme-update/`
4. **最后**才改 `update.json` 里的 `version`
@@ -96,14 +96,27 @@ theme-update/readme.html # 「详情」页,可省
## ⚠️ 自动升级会覆盖主题目录
WordPress 升级主题的做法是**删掉整个 `kratos_yang/` 再解压新包**。
所以任何直接改在服务器主题目录里的东西都会丢,包括:
WordPress 升级主题的做法是**删掉整个 `kratos_yang/` 再解压新包**
(`wp-admin/includes/class-theme-upgrader.php` 里 `clear_destination => true`,
随后 `delete_old_theme()` 递归删除)。所以任何直接改在服务器主题目录里的东西都会丢,
包括手工打的补丁(例如曾经直接在 `footer.php` 里加的 Prism 脚本)。
- `custom/custom.css`、`custom/custom.js`(放本地自定义样式的常用位置)
- 手工打的补丁(例如曾经直接在 `footer.php` 里加的 Prism 脚本)
**自定义样式不再放主题目录。** 早期版本有一个 `custom/` 目录(`custom.css` /
`custom.js` / `custom.php`),是给用户随手加样式的入口,但它位于主题目录内,
每次升级都会被清空 —— 而且 `custom.php` 会被 `require`,等于允许在主题里执行任意
PHP 代码。该模块已在 3.2.2 移除,改为后台选项:
把自定义内容放主题目录外,或者在升级后重新部署。本仓库的 `custom/` 已经纳入版本管理,
修改请改仓库再发布新版本,不要在服务器上直接编辑。
> 后台 → 主题选项 → **自定义代码** → 自定义 CSS / 自定义 JS
这两段内容存在数据库的 `kratos` 选项里,**升级、重装、改主题目录名都不受影响**。
它们分别在主题样式表和主题脚本之后加载,优先级最高。
几个要点:
- 不需要写 `<style>` / `<script>` 标签,直接写 CSS / JS 内容
- 内容不会被当作 HTML 处理,`>`、`<`、`~`、反斜杠转义(如 `content: "\f101"`)都原样保留
- 想彻底清空,把框里内容删掉保存即可(空值会覆盖内置默认值)
- 点“恢复默认”会把「自定义 CSS」还原成主题自带的默认样式
## 换域名 / 退役旧域名