李锋镝的博客

  • 首页
  • 时间轴
  • 说说
  • 每日心情
  • Now
  • 系列文章
  • 论坛
  • 左邻右舍
    • 左邻右舍
    • 博友圈
  • 留言
    • 留言
    • 走心评论
  • 关于
    • 关于我
    • 网站地图
    • 网站统计
    • 另一个网站
    • 我的导航站
    • 赞助
  • 🚇开往
Destiny
自是人生长恨水长东
  1. 首页
  2. 原创
  3. WordPress
  4. 正文

Kratos+ —— Kratos 主题二次开发记录

2026年6月12日 约 2,559 字9 分钟 62 1 0
合集:Kratos+主题第 1 篇 / 共 7 篇
  1. 1Kratos+ —— Kratos 主题二次开发记录当前
  2. 2Kratos+主题新功能预览及功能演示
  3. 3Kratos+主题新功能介绍
  4. 4增加了两套复古皮肤-牛皮纸、千禧网页
  5. 5给主题增加了Now、每日心情、年度回顾、岁月同一天、随机漫步等功能
  6. 6Kratos+ v1.1.14版本更新说明
  7. 7Kratos+ v1.1.16版本更新说明

基于 Seaton Jiang 的 Kratos v4.3.2 二次开发,遵循 GPL-3.0 协议。

仓库:https://github.com/lifengdi/kratos-plus

维护:Dylan Li,版本 1.0.0,发布于 2026-06-11。
主题下载地址:
GitHub:https://github.com/lifengdi/kratos-plus/releases
Gitee:https://gitee.com/lifengdi/kratos-plus/releases


一、为什么要做这件事

原版 Kratos 是个清爽好看的经典 PHP 博客主题,但用一阵子之后我列了一长串想改的地方:

  • 代码块没有语法高亮——技术博客几乎不可用;
  • 布局是写死的 8/4 双栏——窄屏挤、宽屏空;
  • 评论区没有任何反垃圾机制——一夜被刷 200 条 spam;
  • CSF(codestar-framework)框架的 Font Awesome / CodeMirror CDN 全部 404——后台主题设置打开就一堆 console 错;
  • Gutenberg 粘贴 Markdown 时丢语言信息——代码块没有任何语言标记。

干脆 fork 一份独立维护,命名 Kratos+。这篇文档是首版(v1.0.0)的完整改动记录。


二、核心新功能

1. 三引擎代码高亮(最大工程量)

后台 → 全站配置 → 代码高亮(独立 section):

维度 选项
高亮方案 Prism.js(默认) / highlight.js / highlight.php(服务端)
资源加载方式 CDN / 本地缓存(一键预下载所有语言+主题,2MB)
CDN 根路径 默认 jsdelivr,可改 unpkg / 国内镜像
Prism 主题 45 款(核心 8 + prism-themes 扩展 37)
highlight 主题 73 款(hljs 与 highlight.php 共用)
主题预览 实时预览面板(带 toolbar/copy 按钮)
显示行号 仅 Prism / hljs 方案

几个细节决策:

  • 三引擎并存而不是只支持一个:Prism.js 用得最广、可视化好;highlight.js 自带 100+ 语言自动检测;highlight.php 是服务端渲染,对 SEO 和缓存最友好——三种方案各有优势,让作者自选。
  • 本地缓存 = "全量预下载",不是按需懒加载:一次切换、一次下载、之后纯静态服务。这意味着 Apache / Nginx / Caddy / IIS 任何 web 服务器都不需要 rewrite 规则。试过其它路线(PHP 代理、.htaccess rewrite)——都引入了不必要的复杂度,最后回到最朴素的方案。
  • 使用 @highlightjs/cdn-assets 而不是 highlight.js npm 包——后者发布的是 CommonJS(var hljs = require('./core')),浏览器直接 <script> 加载会报 require is not defined;前者才是浏览器可用的 UMD 构建。
  • prism-themes 社区扩展包单独维护版本号(KRATOS_PRISM_THEMES_VER = 1.9.0),独立于 Prism 核心,便于跟随各自更新。

2. Gutenberg 粘贴 Markdown 自动保留语言

这是最折腾的一个功能。问题链:

  1. 在 Gutenberg "代码"块粘贴 Markdown 文本(含 html 围栏);
  2. WordPress 内置 markdown converter (showdown) 转出 <pre><code class="language-html">...;
  3. 但 Gutenberg 的 core/code 区块默认 schema 不接受 <code> 上的 class 属性,DOM cleaner 把 class 剥掉;
  4. 数据库里只剩裸 <pre><code>...,前台靠 highlightAuto 推测——HTML 经常被识别成 xml。

试了好几个方案才解决:

  • ❌ addFilter('blocks.registerBlockType') —— 注册时机晚于 core 块,不生效;
  • ❌ 直接 mutate 已注册块的 transforms.from —— schema 改对了,但 pasteHandler 内部走全局 cleaner,class 仍被剥;
  • ❌ wrap wp.blocks.pasteHandler —— Gutenberg 内部 webpack import,不走 namespace 引用;
  • ✅ 拦截 contenteditable 元素的 paste 事件(capture 阶段,先于 React 委托)→ 解析 Markdown 成结构化片段(heading / paragraph / fence)→ 用 wp.blocks.createBlock('core/code', { content, className: 'language-xxx' }) 直接构造 block 实例,完全跳过 pasteHandler 的清洗链路。

成功后链路终点:数据库存的就是

<!-- wp:code {"className":"language-html"} -->
<pre class="wp-block-code language-html"><code>...</code></pre>
<!-- /wp:code -->

前台 Prism / hljs / highlight.php 三引擎都按 language-html 渲染,零依赖 highlightAuto,100% 准确。

辅助:在区块设置侧边栏加了 "代码语言" 下拉(50+ 主流语言),不写围栏的作者也能直接选。

3. 自定义版面布局

选项 范围 默认 说明
主体宽度 5–11 8 Bootstrap 12 栅格列宽
侧边栏宽度 1–7 4 同上,建议两值之和 ≤ 12
页面主体最大宽度 960px – 不限 1280 大屏 1310px 断点以上的容器 max-width

写了个 PHP helper kratos_layout_cols() 集中处理 clamp 与 fallback;模板里 <div class="col-lg-..."> 全替换成动态读取选项。

同时修复了一个连带 bug:.k-main .details .toolbar 主题 CSS 的卡片样式(margin/padding/box-shadow)跟 Prism toolbar 插件 class 冲突——重置 wrapper、按钮 hover 浮现,跟主题视觉协调。

4. 评论数学验证码

后台 → 全站配置 → 功能配置 → 评论验证码:

  • 开关 + 数字最大值(5–99,默认 10)
  • 运算符随机 + / -,减法时确保 x ≥ y 不出负数
  • 题目存 transient(10 分钟有效),答错或过期一次性失效
  • 答错后 Ajax 自动刷新新题(不需要整页刷新)
  • 答对提交成功后也刷新一道新题,防止下次重复利用 token
  • 静态缓存兼容:HTML 里只占位,DOMContentLoaded 时拉新题——整页缓存(WP Super Cache / Cloudflare)不会让所有访客拿到同一个 token

UI 位置:评论 textarea 下方那一行,紧贴表情按钮右侧([😀] [7 + 3 =] [ ])。

5. 哀悼功能改为全站生效

原版 mourning() 函数里写了 is_home() &&——只在首页变灰。重大社会哀悼场景显然应全站生效,去掉这个条件即可,subtitle 文案也跟着改。


三、若干"框架级"修复

CSF 死 CDN 替换(必修)

CSF 框架硬编码了字节跳动 CDN(lf26-cdn-tos.bytecdntp.com)的 Font Awesome / CodeMirror / Leaflet / WebFontLoader——这家 CDN 在 2024 年下线了。后台打开主题设置就是满屏 console 红字、CodeMirror 加载失败、Leaflet 地图字段挂。

修复:直接改 CSF 内 vendored 副本的 cdn_url,替换为 jsdelivr 上的等价资源:

原 CDN 替换为
lf26-cdn-tos/cdn/font-awesome/5.15.4/... cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@5.15.4/...
lf26-cdn-tos/cdn/codemirror/<v>/... cdn.jsdelivr.net/npm/codemirror@<v>/lib/... 主文件,addon/mode 保持原相对路径
lf26-cdn-tos/cdn/leaflet/<v>/... cdn.jsdelivr.net/npm/leaflet@<v>/dist/...
lf26-cdn-tos/cdn/webfont/1.6.28/... cdn.jsdelivr.net/npm/webfontloader@1.6.28/webfontloader.js

CodeMirror 还有一个前端动态加载 mode 文件的二级问题:CSF 把 cdn_url 传给前端 loadmode 用作根路径,loadmode 在浏览器里运行时拼 <base>/mode/<lang>/<lang>.js,不走 PHP enqueue → style_loader_src filter 摸不到。所以 vendored 副本里 cdn_url 的硬编码必须直接改文件本身。

"主题自带的 code 样式"覆盖代码高亮

主题原本有几条 .k-main .details .article .content pre 规则强制 background: #272822 !important、code { color: #e83e8c },会覆盖任何代码高亮主题。修复:给所有这类规则加 :not([class*="language-"]):not(.hljs) 排除,让 Prism / hljs 标记过的元素跳过主题样式。

文章聚合小工具(Kratos+ - 文章聚合)

侧边栏宽度可调后,原本 .nav-tabs 的 padding 在窄列宽下会让"最新/热点/随机" 3 个 tab 换行。给小工具范围内的 nav 加 flex: 1 1 0 + nowrap + 文字省略,三个 tab 永远在同一行。


四、自动更新

启用 plugin-update-checker(PUC v5)的 GitHub Release 模式:

$kratosPlusUpdater = PucFactory::buildUpdateChecker(
    'https://github.com/lifengdi/kratos-plus/',
    get_template_directory() . '/style.css',
    'kratos-plus'
);
$kratosPlusUpdater->setBranch('main');
$kratosPlusUpdater->getVcsApi()->enableReleaseAssets();

发布流程交给 GitHub Actions(.github/workflows/release.yml):

  1. git push origin v1.x.x 推送 tag;
  2. workflow 自动校验 style.css 的 Version 与 tag 一致;
  3. git archive 出快照、删 .idea/ CLAUDE.md 等开发文件;
  4. 打成 kratos-plus-x.y.z.zip 上传到 GitHub Release。

之后所有装了 Kratos+ 的 WordPress 站后台 → 主题列表会出现"有可用更新"按钮,跟更新插件一样的体验。


五、品牌与版权

字段 值
Theme Name Kratos+
Slug kratos-plus
Version 1.0.0
Author Dylan Li
License GPL-3.0(继承自 Kratos)

按 GPL-3.0 要求保留:

  • 全部 22 个 PHP 文件头里 @author Seaton Jiang 原署名(追加 @author Dylan Li (Kratos+ fork) 共同维护行,未删除);
  • 后台"关于主题 → 版权声明"段落明确说明二次开发关系;
  • LICENSE 文件未动。

前台页脚保持简洁(仅显示 Theme Kratos+ By Dylan Li),原作者致谢放在源代码与后台版权声明里——这符合 GPL-3.0 的最低要求,前台展示属于"礼仪"而非协议义务。


六、踩过的坑(按时间顺序记录,给以后的自己看)

1. CSF subtitle 写 HTML 字面量

后台代码高亮选项的 subtitle 我一开始写了 启用/禁用文章 <pre><code> 代码块语法高亮——浏览器把 <pre><code> 当真元素渲染了,结果选项后面挂着个奇怪的等宽字体小框。改成纯文本就好。

2. admin_print_styles 钩子不传 $hook_suffix

我写了 function (xxx_admin_styles, $hook) { strpos($hook, 'kratos-options') } 想精准注入 CSS——但 admin_print_styles 钩子不传 $hook 参数,只有带后缀的 admin_print_styles-{hook} 才传。结果 $hook = null,函数立刻 return,CSS 永远没输出。改用 get_current_screen()->id 判断。

3. rsync --exclude='vendor/' 的子目录连带屏蔽

不带前导 / 的 rsync exclude 会匹配所有层级里同名目录。结果 inc/update-checker/vendor/(含 Parsedown)和 inc/codestar-framework/assets/scss/vendor/ 都被误删,启用 PUC 自动更新时报 Class "Parsedown" not found。修复:所有排除项加 / 前缀锚定到主题根。

4. 主题目录名重命名时数据库滞后

dylan_kratos → kratos-plus 改了文件夹名后,wp_options 里 stylesheet / template / current_theme 三个键还指向旧 slug,前台直接 fallback 到默认主题。必须同时改三处:源目录、部署目录、数据库三个键。在 PHP 里用一个事务原子化更新这三个键,避免中间状态。

5. 数据库 serialized 数组里的旧路径

主题选项(图片 URL 等 8 处)保存时用了绝对 URL http://.../themes/dylan_kratos/...,目录改名后这些 URL 全 404。不能用 SQL REPLACE,因为 serialized 字符串带长度前缀,简单替换会破坏数据结构。正确做法:unserialize → 递归替换 → serialize。


七、新增的文件 / 目录

路径 用途
inc/theme-codehighlight.php 三引擎代码高亮的所有逻辑(PHP 端)
inc/theme-comment-captcha.php 评论验证码
inc/highlight-php/ scrivo/highlight.php 库(vendored,~1.8MB)
assets/js/codehl-block-editor.js Gutenberg 编辑器扩展(语言下拉 + paste 拦截)
.github/workflows/release.yml GitHub Actions 自动发布 workflow

八、感谢

  • Seaton Jiang —— Kratos 原作者,主题骨架和很多模板逻辑是他的工作;
  • Prism.js / highlight.js / scrivo/highlight.php —— 代码高亮三引擎;
  • PrismJS/prism-themes —— 37 款社区主题;
  • @highlightjs/cdn-assets —— 浏览器可用的 hljs UMD 构建;
  • YahnisElsts/plugin-update-checker —— GitHub Release 自动更新;
  • codestar-framework —— 主题选项框架(CSF)。
除非注明,否则均为李锋镝的博客原创文章,转载必须以链接形式标明本文链接

本文链接:https://www.lifengdi.com/article/wordpress/4724

推荐阅读

  • Kratos+ v1.1.14版本更新说明
  • 增加了两套复古皮肤-牛皮纸、千禧网页
  • Kratos+主题新功能介绍
  • Kratos+ v1.1.16版本更新说明
  • 给主题增加了Now、每日心情、年度回顾、岁月同一天、随机漫步等功能
本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可
标签: Kratos+ WordPress 主题
最后更新:2026年7月16日
相关文章
  • wordpress增加说说功能2025年4月2日
  • Kratos+主题新功能预览及功能演示2026年6月29日
  • WordPress评论添加UserAgent以及地理位置信息2025年12月1日
  • 做了一个WordPress文章热力图插件2025年12月16日
  • Dylan Custom Plugin 1.0.3版本更新说明2025年4月22日

李锋镝

既然选择了远方,便只顾风雨兼程。

打赏 点赞
合集下一篇 >
1234567891112131415161718192021222324252627282930313233343536373839404142434446474849505152535455575859606162636465666769727476777879808182858687909293949596979899
取消回复

文章评论

还没有评论,快来抢沙发吧~

Your time is limited, so don't waste it living someone else's life. Don't be trapped by dogma -- which is living with the results of other people's thinking. Don't let the noise of other's opinions drown out your own inner voice. And most important, have the courage to follow your heart and intuition. They somehow already know what you truly want to become. Everything else is secondary.

听点儿音乐吧 朋友~
文章目录
最新 热点 随机
最新 热点 随机
每日早报 · 2026年8月18日 写了一个订阅每日新闻的WP插件 每日早报 · 2026年8月17日 每日早报 · 2026年8月16日 每日早报 · 2026年8月15日 每日早报 · 2026年8月14日
给主题增加了Now、每日心情、年度回顾、岁月同一天、随机漫步等功能Kratos+ v1.1.16版本更新说明AI时代,个人技术博客的出路在哪里?增加了两套复古皮肤-牛皮纸、千禧网页这个域名注册整整十年了,十年时间,真快啊Kratos+ v1.1.14版本更新说明
CC知识共享协议各协议内容解释 深度解析多级缓存架构:从设计到落地,彻底解决数据一致性难题 从零开始入门 K8s | Kubernetes 网络概念及策略控制 AI原生数据库新标杆:seekdb深度解析,轻量架构与混合搜索的双重革命 结合Apollo配置中心实现日志级别动态配置 使用RocketMQ时,服务启动过程中,Consumer在服务未启动时消费消息问题处理
最近评论
李锋镝 发布于 3 小时前(08月18日) 给主题加了个功能,可以在RSS中排除指定分类,哈哈哈
李锋镝 发布于 4 小时前(08月18日) :8: 喜欢就好
不凡 发布于 14 小时前(08月17日) 哇,配色真好看,观感很舒服! :52:
李锋镝 发布于 17 小时前(08月17日) 哈哈哈,那个插件我之前也用过,那个内容都是固定的,我这个每天不同的时间拉取数据也不一样,等我研究研究...
Hary 发布于 17 小时前(08月17日) emmm大哥,这样每天输出到博客,然后别人订阅rss全是这个,有点不太好,之前很流行一段时间每天60...
标签聚合
Redis MQ JVM MySQL 多线程 ElasticSearch 日常 Claude IDEA AI 分布式 SpringBoot SQL AI编程 K8s 数据库 WordPress JAVA 架构 Spring
友情链接
  • 瓦匠个人小站
  • 若梦博客
  • 九仞之行
  • 老张博客
  • 知向前端
  • 哥斯拉
  • Honesty
  • 韩情脉脉
  • 皮皮社
  • Serendipity
  • Mr.Sun的博客
  • 韩小韩博客
  • 志文工作室
  • 懋和道人
  • 临窗旋墨
  • 搬砖日记
  • 林羽凡
  • 彬红茶日记
  • 蜗牛工作室
  • sssr7844的博客

COPYRIGHT © 2026 lifengdi.com. ALL RIGHTS RESERVED.

正在博友圈履约中

域名年龄

Theme Kratos+ By Dylan Li

津ICP备2024022503号-3

京公网安备11011502039375号