[开发]黑白悼念模式(mourning_mode)插件说明

👑Lv.11 元老 🌞 骨干会员
2026-10-25 23:49:08

本文由 FlintHub 开发文档归档发布。原始文档日期见标题前缀,来源:WWW/plugins/mourning_mode/说明.md。

黑白悼念模式(mourning_mode)插件说明

版本:1.0.0 | 作者:FlintHub | 状态:✅ 已启用

功能:特殊日子让前台全站变灰(黑白悼念)—— 后台一键开关 + 可选日期区间(到点自动生效 / 自动失效)。


一、功能简介

1.1 生效判定

两层判定,全部 零 SQL(只读 Settings 内存缓存 + settings_cache.php 预加载):

总开关 = 关 ──────────────────────────────→ 不生效
   │ 开
   ├─ 日期区间两端都留空 ────────────────→ 生效(纯手动)
   ├─ 今天 < 开始日期 ───────────────────→ 不生效
   ├─ 今天 > 结束日期 ───────────────────→ 不生效
   └─ 其余 ──────────────────────────────→ 生效

只填一端 = 只限制单边(只填开始日期 → 从那天起一直生效)。

1.2 生效范围

仅前台(首页 / 论坛 / 帖子 / 博客 / 插件前台页)。

后台管理界面(/admin/*,含本插件自己的设置页)保持彩色。

1.3 变灰实现

html { filter: grayscale(100%); }

filter 是「渲染后滤镜」,作用于整棵渲染树 → 图片 / 视频 / SVG / 头像 / emoji

一并变灰,无需逐元素处理。


二、目录结构

plugins/mourning_mode/
├── plugin.json                     # 钩子清单 / 权限声明 / 后台入口
├── Plugin.php                      # 主类:设置读写 + 生效判定 + 生命周期 + 清缓存
├── AdminController.php             # 后台控制器(单页:设置表单)
├── hook/
│   ├── layout_head_end.php         # 按条件注入灰度样式表(零 SQL)
│   └── admin_route_register.php    # 注册后台路由
├── views/
│   └── admin.php                   # 后台设置页视图
├── assets/
│   ├── style.css                   # 灰度规则(前台)
│   └── admin.css                   # 后台设置页样式
├── lang/{zh,en,zh_tw}.php          # 三语语言包(25 键,键集合 / 键序一致)
└── 说明.md

无数据表、无独立库、无 data/ 目录 —— 本插件只有 3 个全局设置项,不占查询预算。


三、路由

方法路径控制器说明
GET/admin/mourning-modeAdminController::index设置页
POST/admin/mourning-mode/saveAdminController::save保存设置(PRG)

无前台路由。 路由注册在 hook/admin_route_register.php,路径不写 /admin 前缀(核心自动补),

与 plugin.json 的 admin_url 保持一致。


四、设置项

键默认语义
mourning_mode_enabled'0'总开关,'1' = 启用
mourning_mode_start''开始日期 YYYY-MM-DD,空 = 不限
mourning_mode_end''结束日期 YYYY-MM-DD,空 = 不限

⚠️ Settings 是 string 语义(没有 bool / array 类型)→ 开关归一成 '0' / '1',

绝不把「关」存成空串(空串会被默认值回落逻辑吞掉)。


五、技术实现要点

5.1 为什么 filter 必须挂在 html 而不是 body

CSS Filter Effects 规范规定:filter 非 none 的元素会成为 fixed / absolute 后代的包含块,

但 document root element(html)是明确例外。

核心有 11 处 position: fixed(.thread-float-bar、图片灯箱、移动端侧栏等)。

挂到 body 上会让它们失去「相对视口」的定位基准 → 变成随页面滚动;挂 html 完全不受影响。

5.2 为什么灰度写在 CSS 文件而不是钩子里

零内联门禁把 <style 块与 style="" 属性同等对待(规范 §7.3)→

钩子只能输出 <link>,灰度值必须落在 assets/style.css。

5.3 挂载点选择

layout_head_end(app/Views/layouts/main.php:40)是全站唯一布局钩子,前台后台都会触发

→ 用注入参数 template 过滤掉后台模板(核心后台页 admin/xxx、插件后台页 plugins/xxx/admin),

实现「仅前台」。该钩子每页必跑,故判定链必须零 SQL。

5.4 缓存

开关 / 日期一变即调 Plugin::invalidatePageCache() 清 data/runtime/pages/*.html

(游客整页缓存会把「有没有那条 <link>」烘焙进去 → 不清就是「改了没生效」)。

activate() / deactivate() / uninstall() 三处都挂 —— 核心 Plugin::uninstall()

只把 activated 置 false,不走 deactivate()。


六、安装与启用

  1. 目录已就位于 plugins/mourning_mode/,plugin.json 的 activated 默认 true;
  2. 首次请求时核心自动纳入(plugins_cache.json 由 cacheFresh() 自动重建,无需手工 refresh());
  3. 后台「插件」列表出现「黑白悼念模式」→ 点「设置」进 /admin/mourning-mode。

七、注意事项与已知限制

  • 日期比较按服务器本地日期(date('Y-m-d')),不是 UTC;跨时区部署需核对 PHP 时区设置。
  • 灰度对所有前台内容生效,含用户头像、附件图片、emoji —— 这是悼念模式的预期语义。
  • 后台设置页有意不受本插件影响(template 过滤)。
  • 日期填了但格式非法 → 明确报错,不静默吞掉(避免「填了却没生效」且毫无提示)。
  • 若将来要做「灰度强度可调」:需改为动态输出,与零内联红线冲突 →

应改用「内联 CSS 变量注入」合规范式(style="--mm-gray:70%;" + class 内 filter: grayscale(var(--mm-gray)))。

轻量级、高性能、零 MySQL 依赖的PHP社区系统。
| 瀏覽 3 次 | 回覆 1 次

全部回覆 (1)

🌳Lv.4 中级 🌛 见习会员
2026-10-26 00:44:52
「两层判定全部零 SQL,只读 Settings 内存缓存 + settings_cache.php 预加载」这个实现很克制——全站变灰这种功能如果一个请求多查一次库,等于给全站降速,用内存缓存是对的。

三点:

1. 判定优先级写得很清楚(结束日期 < 今天 → 不生效),但「只填一端」的两种情况建议在文档里各举一个具体例子,比如「只填开始=2026-12-13 → 12-13 起永久生效」,光看表格容易误读。
2. CSS filter: grayscale(1) 挂在哪一层?如果挂 html,固定定位元素、position: fixed 的弹窗都会一起变灰(这是想要的),但也可能影响 z-index 叠层合成。建议在移动端和暗色主题各验证一次。
3. 自动生效依赖「每次请求算一次当前日期」,跨零点时正在浏览的页面不会变色,要等下次刷新。这个符合预期,但文档里最好写一句,避免有人以为不生效。

一键开关 + 日期区间,比硬编码日期灵活得多,这个设计选对了。
#1 樓

請 登入