Files
wordpress-kratos-yang/inc/theme-custom-code.php
T

159 lines
5.3 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
/**
* 自定义代码(CSS / JS)
*
* 这两段代码存在主题选项里(数据库 wp_options 的 kratos 项),不存主题目录。
* 原因:WordPress 升级/更新主题时会**清空整个主题目录**再解压
* (wp-admin/includes/class-theme-upgrader.php 里 clear_destination = true,
* 随后 delete_old_theme() 递归删除),写在主题目录里的任何自定义文件都会丢。
* 放进选项表就与主题文件解耦,升级、重装、换主题目录名都不影响。
*
* @author Yongquan Yang <yangyq.net>
* @license MIT License
*/
/**
* 默认自定义 CSS:空。
*
* 历史沿革(3.2.29 变更):
* 早年主题目录下有个 custom 子目录当「自定义样式」入口,后来改成配置项,
* 那批规则(段落缩进、h2 蓝条、列表缩进)就作为默认值下发,并被写进了库。
* 3.2.29 把它们并入主题公共样式 assets/css/site.css,配置项改为默认空 ——
* 「站点通用样式」本该跟着主题走,「自定义代码」留给临时覆盖。
*
* ⚠️ 不要再用旧的那段 CSS 给配置项兜底:site.css 已经在输出同样的规则,
* 再兜底一次就等于全站样式写两遍,且会让后台的框永远显示旧内容。
*/
function yang_default_custom_css()
{
return '';
}
/**
* 3.2.29 之前作为默认值下发、并已写进数据库的那段 CSS。
*
* 只用于两件事:
* ① 识别「库里存的还是历史默认值」——输出时跳过,避免与 site.css 重复;
* ② 迁移时比对,确认是可以安全清空的那一份(不是站长自己改过的内容)。
*
* 这里有意保留原样的换行与缩进:比对前会先做空白归一化,
* 所以即使库里的换行是 CRLF、这里的是 LF,也能正确匹配。
*/
function yang_legacy_custom_css()
{
return <<<'CSS'
.article .content p{ text-indent:2em }
.k-main .details .article .content h2 {
margin: 16px -16px;
padding: 0 10px;
border-left: 5px solid #00a2ff;
background-color: rgba(243, 243, 243, 0.7);
font-size: 20px;
line-height: 41px;
}
ul{
margin-left:2em;
}
ol{
margin-left:2em;
}
ol > li{
line-height: 1.8;
}
ul > li{
line-height: 1.8;
}
CSS;
}
/**
* CSS 空白归一化:只用于「是不是同一段代码」的比对,不用于输出。
*
* 处理:CRLF/CR → LF、连续空白压成一个空格、去掉 `{ } : ; , >` 两侧空白、
* 去掉块尾多余的 `;`。这样「同一条规则的不同缩进/换行」会得到同一个字符串。
*/
function yang_normalize_css($css)
{
if (!is_string($css)) {
return '';
}
$css = str_replace(array("\r\n", "\r"), "\n", $css);
$css = preg_replace('/\s+/', ' ', $css);
$css = preg_replace('/\s*([{}:;,>])\s*/', '$1', $css);
$css = str_replace(';}', '}', $css);
return trim($css);
}
/**
* 库里存的这段 CSS 是否就是「已并入 site.css 的历史默认值」。
*/
function yang_is_legacy_custom_css($css)
{
$normalized = yang_normalize_css($css);
return $normalized !== '' && $normalized === yang_normalize_css(yang_legacy_custom_css());
}
/**
* 取自定义 CSS(未设置时为空)。
*
* 历史默认值已被 site.css 接管:库里若还是它,这里返回空串,
* 避免同一批规则在页面上出现两遍。真正自己改过的内容原样返回。
*/
function yang_custom_css()
{
$css = kratos_option('g_custom_css', yang_default_custom_css());
if (!is_string($css)) {
return '';
}
if (yang_is_legacy_custom_css($css)) {
return '';
}
return $css;
}
/**
* 取自定义 JS(未设置时为空)
*/
function yang_custom_js()
{
$js = kratos_option('g_custom_js', '');
return is_string($js) ? $js : '';
}
/**
* 一次性迁移:把库里那段「历史默认 CSS」清成空串。
*
* 为什么需要:std / 默认值只在「后台预填」和「恢复默认」时起作用,
* 运行时 kratos_option() 只查库 —— 库里的旧值不清,后台那个框就永远
* 显示着已经并入 site.css 的旧内容,站长以为它还在生效。
*
* 为什么挂在 admin_init:
* · 只影响后台请求,前台一个写操作都不做;
* · 用户升级后第一次进后台就自动完成,不需要额外操作。
*
* ⚠️ 三条护栏:
* ① 有 $_POST 时直接退出 —— 本函数会走 update_option(),而 update_option()
* 内部会跑 sanitize_option_kratos(= validate_options)。那个回调看到
* $_POST['reset'] 会返回「全部默认值」⇒ 用户在后台点保存/恢复默认的
* 那一下,配置会被我们顺手改成默认值。所以提交请求里绝不插手。
* ② 只清「与历史默认值逐字等价」的内容 —— 站长自己改过的一个字都不碰。
* ③ 清空而不是删键:删键会被 validate_options 用库里的旧值补回来。
*/
function yang_custom_code_migrate()
{
if (!empty($_POST)) {
return;
}
$saved = get_option('kratos');
if (!is_array($saved) || !isset($saved['g_custom_css'])) {
return;
}
if (!yang_is_legacy_custom_css($saved['g_custom_css'])) {
return;
}
$saved['g_custom_css'] = '';
update_option('kratos', $saved);
}
add_action('admin_init', 'yang_custom_code_migrate');