李锋镝的博客

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

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

2026年6月12日 152点热度 1人点赞 0条评论

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

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

维护:Dylan Li,版本 1.0.0,发布于 2026-06-11。


一、为什么要做这件事

原版 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+主题新功能预览及功能演示
  • 做了一个WordPress文章热力图插件
  • WordPress实现用户评论等级排行榜插件
  • WordPress评论添加UserAgent以及地理位置信息
  • Dylan Custom Plugin 1.0.3版本更新说明
本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可
标签: Kratos+ WordPress 主题
最后更新:2026年6月12日

李锋镝

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

打赏 点赞
< 上一篇
下一篇 >
1234567891112131415161718192021222324252627282930313233343536373839404142434446474849505152535455575859606162636465666769727476777879808182858687909293949596979899
取消回复
…

文章评论

秋天是倒放的春天,晚安是爱你的序篇。

那年今日(07月03日)

  • 2005年:西班牙正式通过同性婚姻相关法案
  • 1969年:英国滚石乐队的创始团员布莱恩·琼斯去世
  • 1876年:中国第一条铁路淞沪铁路正式通车运营
  • 1518年:中国明代医学家兼药物学家李时珍出生
  • 1062年:中国北宋官员包拯去世
  • 更多历史事件
最新 热点 随机
最新 热点 随机
Kratos+主题新功能预览及功能演示 SpringBoot DeferredLog 完整详解 LiteLLM 本地代理搭建 Claude-HUD 使用文档 Kratos+ —— Kratos 主题二次开发记录 译文:如何将单体应用拆解为微服务
AI时代,个人技术博客的出路在哪里?这个域名注册整整十年了,十年时间,真快啊WordPress实现用户评论等级排行榜插件WordPress网站换了个字体,差点儿把样式换崩了做了一个WordPress文章热力图插件千万级大表新增字段实战指南:告别锁表与业务中断
Auld Lang Syne 缓存架构实战指南:6大核心缓存技术深度解析与落地方案 阿里巴巴的26款超神Java开源项目 Claude Code全维度实战指南:从入门到精通,解锁AI编程新范式 岁末 海琴烟~~~
最近评论
李锋镝 发布于 4 天前(06月30日) 目前是每天一换,一个星期不重样 :41:
不凡 发布于 4 天前(06月29日) 主题配色挺好看。 :2:
李锋镝 发布于 5 天前(06月29日) 已经更新了~
懋和道人 发布于 5 天前(06月29日) 境外与附件不能访问,其他都是正常的,如果不正常可以通过更换ip访问。
李锋镝 发布于 5 天前(06月29日) 403呀道长
标签聚合
SQL 多线程 日常 IDEA 数据库 ElasticSearch Spring AI编程 JVM JAVA SpringBoot MCP 分布式 MySQL docker AI 架构 K8s Redis WordPress
友情链接
  • Blogs·CN
  • Honesty
  • Mr.Sun的博客
  • 临窗旋墨
  • 哥斯拉
  • 彬红茶日记
  • 志文工作室
  • 懋和道人
  • 拾趣博客导航
  • 搬砖日记
  • 旧时繁华
  • 林羽凡
  • 瓦匠个人小站
  • 皮皮社
  • 知向前端
  • 蜗牛工作室
  • 韩小韩博客
  • 风渡言

COPYRIGHT © 2026 lifengdi.com. ALL RIGHTS RESERVED.

域名年龄

Theme Kratos+ By Dylan Li

津ICP备2024022503号-3

京公网安备11011502039375号