Gmeek 插件与功能全景调研:系列教程总揽(第 0 篇)
这是 Gmeek 系列教程的第 0 篇:一张完整的功能地图。本文不教具体操作,而是回答两个问题——Gmeek 到底还藏着哪些能力?哪些值得搬、哪些不值得搬?文中每个结论都附了一手出处(官方源码、作者博客、社区 issue、原始教程),后续每动手复现一个功能,就会发一篇编号教程并在文末路线图里打勾。博客现阶段的内容方向也由此确定:先把 Gmeek 本身玩透。
怎么读这篇文章
- 想抄作业:直接跳到文末「系列教程路线图」,按编号等后续教程;
- 想自己深挖:每个功能都附了出处链接,优先看源码而不是二手转述;
- 想看结论:每节末尾都有"叶扬的判断"。
本系列的编号约定:第 0 篇是总揽,之后每篇教程以 G01、G02…… 编号,文末路线图会持续更新。前面三篇相关文章是本系列的前传:
调查的一手来源
结论不是凭印象,全部来自以下材料交叉验证:
| 来源 | 链接 | 价值 |
|---|---|---|
| Gmeek 源码仓库 | Meekdai/Gmeek | plugins/、templates/、Gmeek.py 是最终事实依据 |
| 官方插件目录 | plugins/ | 官方全部 5 个插件 |
| 构建脚本 | Gmeek.py | 所有配置项的默认值与解析逻辑 |
| 官方插件进阶教程 | 《【Gmeek 进阶】插件功能的使用》 | 作者亲自维护的插件收录文,好插件会被收入 |
| 作者本人博客配置 | meekdai.github.io/config.json | 官方"最佳实践"样本 |
| Issue #167 | 插件分享基地 | 社区插件集散地 |
| Issue #145 | SEO 优化相关问题 | 作者确认 RSS 可直接当 sitemap 提交 |
| Issue #186 | 提一些需求 | 外链新窗口、数字分页条等社区需求出处 |
| Issue #100 / #134 | 目录需求、代码复制建议 | 功能演进的来龙去脉 |
一、官方插件全档案
官方插件一共 5 个,全部位于源码仓库 plugins/ 目录,机制完全一致:一个自包含 JS,放进 static/ 目录,用配置字段注入页面,CSS 自己动态注入。这是 Gmeek 插件哲学的核心——不改上游模板,升级零冲突,删掉一行配置即回退。
1. GmeekVercount.js —— 访问统计(已装)
- 功能:站点总 PV/UV、文章页 PV,数据自存在 Vercount 服务,无需注册。
- 出处:插件源码
- 官方态度:进阶教程里首推。替代的不蒜子(busuanzi)已长期无人维护,且在 Safari 下计数不准。
- 叶扬的判断:保留。只记数字、不追踪个人身份,符合第 4 篇立的统计克制原则。另一个统计插件
GmeekBSZ.js(不蒜子)不要装。
2. GmeekTOC.js —— 右侧文章目录(已装 已退役留档,见 G16)
- 功能:扫描正文
h1~h6生成固定在右侧的目录,按标题级别缩进,窄屏自动收为文章内块,附 Top 回顶按钮。零依赖,100 行。 - 出处:插件源码;接入全过程见本站第 3 篇教程。
- 关键坑:只能走
script字段(仅文章页注入),不能放allHead——首页没有id="content"元素,会抛 TypeError。 - 叶扬的判断:官方文档站自己在用,配色全走 Primer CSS 变量自动适配暗色。本站第一个接入的插件(前传 #3),平铺目录无 scrollspy;G16 起被本地化改造的 GmeekTocBot 接替,config 摘除引用、文件留在
static/plugins/留档可回退。
3. lightbox.js —— 图片灯箱(✅ 已装,见 G05)
- 功能:文章图片点击放大,支持滚轮缩放、左右键切换上一张/下一张、触屏滑动、相邻图片预加载、毛玻璃遮罩、点遮罩关闭。
- 出处:插件源码(357 行,零外部依赖,所有样式与 DOM 都由插件自建);官方进阶教程收录,由社区用户 Tiengming 贡献。
- 叶扬的判断:官方插件里完成度最高的一个,G05 已接入(
static/plugins/lightbox.js+ configscript拼接);教程里用 og.png/favicon.svg 两张图做了可点击演示。
4. articletoc.js —— 悬浮按钮式目录(✅ 已装,见 G14)
- 功能:不在正文里占位置,而是在右下角放一个 ☰ 圆形按钮,点击弹出目录浮层,再点外部关闭;自带亮/暗两套 CSS 变量。
- 出处:插件源码,同为 Tiengming 贡献。
- 叶扬的判断:原版与 GmeekTOC 同名
.toc,同时加载会被浮层的opacity:0;visibility:hidden连坐藏掉桌面目录,所以官方只让二选一。G14 已用类名隔离(.toc-mobile)实现共存:桌面 >1249px 常驻右侧目录、圆形按钮隐藏;≤1249px 隐藏桌面目录退化出的文首静态块、右下角 ☰ 浮层当班(G16 起桌面目录换成 GmeekTocBot,契约不变、分工不变)。另把原版prefers-color-scheme暗色换成 Primer 变量(#196 三态失配),补空标题守卫、点链接/Esc 收起与 aria-expanded 键盘可达。
5. GmeekTocBot.js —— tocbot 版目录(✅ 已本地化接入,见 G16)
- 功能:封装成熟库 tocbot,视觉层级更好,独有滚动时高亮当前章节能力。
- 出处:插件源码;依赖
cdnjs.cloudflare.com上的 tocbot 4.27.4。 - 叶扬的判断:功能最强但原版依赖第三方 CDN,与本站"静态资源全部本地化"的原则冲突。G16 已按当年预案落地:tocbot 4.27.4 引擎(11KB)下载到
static/tocbot/tocbot.min.js,CSS 六条规则内联并全换 Primer 变量;适配版static/plugins/GmeekTocBot.js另修官方壳六处将就(id 缺 toLowerCase、100vh 空白 div、容器清空、window.onscroll 覆盖、无空标题守卫、暗色裸奔),接替 GmeekTOC 接管桌面目录。
插件组合用法(官方进阶教程原文给出的方式):多个插件可以直接拼在同一个字段里:
"script":"<script src='...GmeekTOC.js'></script><script src='...lightbox.js'></script>"
二、改一行配置就能解锁的框架能力
读 Gmeek.py 第 91 行的默认配置字典和作者本人博客的 config.json,发现一大批框架早就支持、但本站配置里没写的能力。这是性价比最高的一层:不用写任何代码。
固定页面与导航
| 配置项 | 作用 | 出处/样本 |
|---|---|---|
singlePage |
固定页面机制:值是 label 名数组,如 ["about"]。新建一个带 about 标签的 issue,框架会生成根路径下的独立页 about.html,不进文章列表,页头自动出现入口按钮 |
作者配置 "singlePage":["link","about"],对应 about 页 |
iconList |
定义页头按钮的 SVG 路径(16px)。内置 sun/moon/sync/search/rss/upload/post/home/github/copy/check,自定义页面按钮需在此配图标 | Gmeek.py:215 按钮渲染逻辑 |
exlink |
页头外部链接按钮,如作者的 "music":"https://music.meekdai.com" |
作者配置实测 |
这正是第 4 篇路线图里 P0「About 页面」的官方正解,已由 G01 完成(含一个真实踩坑:新增 singlePage 后必须手动全局重建)。
页脚信息
| 配置项 | 作用 | 出处 |
|---|---|---|
bottomText |
全站页脚底部追加一行自定义文字,作者写的是 ❤️ 转载文章请注明出处,谢谢!❤️ |
footer.html |
startSite |
建站日期(如 "02/16/2015"),页脚自动显示"本站已运行 N 天" |
footer.html 内联脚本 |
filingNum |
ICP 备案号,自动链到工信部备案系统 | 绑定国内备案域名后才有用 |
bottomText 一举解决路线图里的「文末版权声明」,已由 G02 完成(另含 startSite 运行天数与日期格式的时区坑)。
身份与分享
| 配置项 | 作用 | 备注 |
|---|---|---|
faviconUrl |
浏览器标签页图标;不配置时默认复用 avatarUrl |
作者用的是自制 SVG |
ogImage |
Open Graph 分享卡片封面;不配置时默认头像 | 文章级还能单独覆盖 |
displayTitle |
页头显示标题,默认与 title 一致 |
想让站名短、标题完整时用 |
homeUrl |
站点绝对地址 | 绑定自定义域名后必须配,否则分页/RSS 链接错乱 |
favicon + ogImage 已由 G03 完成:自制"叶"字 SVG 图标(明暗自适应)+ Pillow 生成 1200×630 PNG 封面;注意 ogImage 只认位图绝对 URL,SVG 不行。
注入与自定义(插件体系的另一半)
| 配置项 | 注入位置 | 加载范围 |
|---|---|---|
allHead |
所有页面 <head> |
全站(统计脚本用它) |
head |
文章页 {% block head %} |
仅文章页头部 |
script |
文章页底部 | 文章级插件(TOC、lightbox) |
style |
文章页 | 文章级 CSS |
indexScript / indexStyle |
首页与列表页 | 仅列表页 |
出处:模板 base.html、post.html、plist.html 中的注入点,以及 Gmeek.py:91 默认值。
外观与排版
| 配置项 | 作用 | 默认 |
|---|---|---|
themeMode |
manual(亮/暗/跟随系统三态手动切换)或 fix 固定 |
manual |
dayTheme / nightTheme |
GitHub 主题名,可换 dark_dimmed、dark_colorblind 等 |
light / dark |
commentLabelColor |
标签颜色 | #006b75 |
yearColorList |
按年份轮换的日期标签色,作者博客四种颜色 | 四色数组 |
onePageListNum |
首页每页文章数,超过自动分页 | 15 |
primerCSS |
Primer CSS 地址,默认已是南科大国内镜像,国内访问无需折腾 | mirrors.sustech.edu.cn |
i18n |
CN / EN / RU 界面语言 |
CN |
showPostSource |
1 显示文末"Issue 原文"按钮,0 隐藏 |
1 |
URL 与订阅
| 配置项 | 作用 |
|---|---|
urlMode |
文章 URL 模式:pinyin(标题转拼音,默认)/ issue(本站使用,/post/编号.html,永久不受改标题影响)/ ru_translit |
rssSplit |
RSS 摘要截断规则:sentence(第一句句号)或其他自定义分隔符 |
needComment |
1 开评论 / 0 全站关闭 utterances |
UTC |
时区偏移,默认 +8 |
三、单篇文章的"隐藏语法"
Gmeek.py:355 会解析每篇 issue 正文最后一行的特殊 HTML 注释,实现文章级配置,这是官方进阶教程里明确支持、但很多人不知道的功能:
<!-- ##{"script":"<script src='...'></script>","style":"...","ogImage":"https://.../cover.png","timestamp":1700000000}## -->| 字段 | 用途 |
|---|---|
script / style / head |
只给这一篇注入插件和样式(如只有一篇多图文章需要 lightbox) |
ogImage |
单篇专属分享封面 |
timestamp |
自定义发布时间戳,补发旧文、迁移文章时让排序归位 |
G06 已完成(教程):文章自身就是活 demo——末行 JSON 给本篇注入了 h2 绿竖条、文末虚线徽章和控制台彩蛋。补充两个实测细节:解析行在新版源码为 Gmeek.py:357;gh API 发布的 LF 正文会被 GitHub 规范化为 CRLF(backup 实锤),所以换行坑只存在于本地调试。
四、你可能没意识到的开箱功能
以下能力不用配置、不用插件,写 Markdown 时直接存在:
- 代码块一键复制:GitHub 同款 copy/check 图标按钮,post.html 内置(对应早期社区 issue #134 的诉求,现已官方解决)。
- 数学公式按需加载:正文直接写
$E=mc^2$(行内)或$$...$$(块级),GitHub 渲染成<math-renderer>标签后,框架剥掉标签壳、注入 MathJax 3(jsdelivr CDN),不写公式的文章零开销(G07 已实测;坑:正文中的美元金额要用反引号包,避免成对$被当公式)。 - GitHub Alert 提示块:
> [!NOTE]、> [!TIP]、> [!IMPORT]、> [!WARNING]、> [!CAUTION]自动渲染成 GitHub 官网同款彩色边框块,框架检测到markdown-alert-title自动补五套配色(Gmeek.py:159起,颜色走 Primer CSS 变量,明暗自适应)。注意 API 渲染的标题是英文 Note/Tip/…,静态页不做本地化。 - 三态主题与评论联动:亮 → 暗 → 跟随系统循环;切换时通过
postMessage让 utterances 评论 iframe 同步换肤(base.html:54)。 - 列表分页:文章数超过
onePageListNum,首页自动出现上一页/下一页。 - 每日定时重建:工作流除了监听 issue 事件,还有一条
schedule: cron("0 16 * * *"),即北京时间每天 0:00 自动全量重建一次。Webhook 丢失、改了配置忘记手动构建,第二天都会自愈。注意:Issue 事件只触发增量构建,config.json的结构性变更(如新增 singlePage)不会被加载,必须手动跑一次全局重建——G01 实操时踩过这个坑。 - Markdown 原文自动备份:每次构建把 issue 正文存进仓库
backup/目录,git clone即整站离线副本。 - RSS 即 sitemap:见下节,单独说。
写作技巧已由 G07 完成:Alert/公式零配置;Mermaid 非内置(GitHub API 只语法高亮不出图)。G15 已把 mermaid 升级为自动检测、按需加载:static/plugins/GmeekMermaid.js 检测到 highlight-source-mermaid 块才动态加载 static/mermaid.min.js(v11,3.5MB),跟随三态主题重绘,作者零配置——G07 时代「含图文章末行手写挂载 JSON」的旧三件套已退役(末行 JSON 漏写即静默失败,是 G15 案发根因)。另有内联反引号 直出 HTML 的彩蛋(围栏代码块不生效)。
五、SEO:被问得最多,答案却最简单
社区 issue #145 里有人建议生成 sitemap.xml,作者的回复是:rss.xml 已包含全站所有重要页面链接,他自己就是把 rss.xml 提交给 Google 的;提问者随后验证,必应和谷歌都能正常识别 RSS 作为站点地图。
G04 已落地(教程):
- Google Search Console / Bing 站长工具直接提交
rss.xml即可(Bing 添加站点时还能从 GSC 一键导入,验证状态继承); - 百度的 sitemap 工具按 sitemaps.org 协议解析、不认 RSS,已在工作流新增
sitemap_gen.py,每次构建从postList.json自动生成标准sitemap.xml,三家都提交它做双保险; - RSS 之外,
robots.txt和自定义404.html直接放进static/根目录即可,构建时原样复制到站点根,GitHub Pages 原生识别(✅ 已完成,见 G11:robots 显式 Allow + Sitemap 绝对 URL;404 独立页 noindex、三态主题读 meek_theme、fetch 最新 5 篇)。
六、社区生态盘点:有宝贝,也有大坑
Gmeek 没有独立插件市场,issue #167「插件分享基地」事实上承担了这个角色。翻遍社区代码后:
值得借鉴的:
- 数字分页条 ✅:把"上一页/下一页"换成 1/2/3 页码,文章几十篇以后有用,issue #186 需求 2。社区李轶凡《给博客添加数字分页条》提供了思路,但 2026-09 调研时原站 DNS 失联、GitHub 仓库源码已撤、Wayback 无存档,已完成见 G13(借鉴失败转为自研):
static/plugins/GmeekPager.js,90 行零 CSS——复用 Primer 21 内建.current/.gap样式与三档响应式显隐;保留框架原生 prev/next 节点只插中间数字;config.indexScript首次启用(仅注入 index/pageN,tag 页不注入);fetch postList.json 计数过滤 labelColorDict;≤7 页全显、否则首尾页+当前页±1+省略号;单页/失败/超界三态静默降级。 - 外链新窗口打开 ✅:同 issue #186 的头号需求,已完成见 G12。
static/plugins/GmeekExternal.js:URL 构造器按 hostname 判内外(协议相对 URL/自家绝对 URL 都不误判),外链补target=_blank+ 合并rel=noopener;显式 target 不覆盖、rel 只合并不替换;不自动加 nofollow(SEO)、不加 noreferrer(保留来路)。
看看就好、不要搬的:
- 社区用户 luliy6 的
enhance.js:约 5884 行的整站换肤方案——开屏动画、全屏 Hero、六张分类卡片、APlayer 音乐播放器、抽屉式菜单。代码本身值得学习"一个 JS 能做到什么程度",但它与本系列第 4 篇立的三条规矩(静态优先、走插件机制不改模板、为长期写作服务)全部冲突,明确不借鉴。 - GitHub 代码搜索能找到的其他"插件",90% 是把官方 5 个 JS 复制改名,无新东西。
七、框架的空白:需要自研的功能
对照第 4 篇的清单,以下功能官方与社区都没有可靠现成方案,需要自己写插件。好在 Gmeek 把数据都放在了 postList.json,自研难度不高,这也会是本系列最"硬核"的几篇:
| 功能 | 实现思路 | 编号 |
|---|---|---|
已完成,见 G08:static/plugins/GmeekPrevNext.js,90 行零依赖;URL 正则定位当前篇(顺带防 about 页)、createdDate+编号排序(兼容 timestamp 补发)、Primer 变量自适应暗色、插在评论按钮前、首尾显示禁用占位 |
G08 ✅ | |
已完成,见 G09:static/plugins/GmeekReadTime.js,50 行零依赖;CJK 汉字按字(三个表意文字区段,码位转义防同形字)+ 拉丁串按词混合计数、标点不计、代码块计入;中文 400 字/分钟,不足 1 分钟按 1 分钟;插在 #content 最前;Primer 变量三态适配;手机端仅缩字号不重排 |
G09 ✅ | |
已完成,见 G10:新增 archive 固定页(issue #16,只打 archive 标签)+ static/plugins/GmeekArchive.js;Gmeek-html 彩蛋写挂载点 div;读 postList.json 过滤 labelColorDict 假键、日期倒序+编号兜底、按年分组、sticky 年份与时间线 CSS;iconList 配 Octicon archive 图标;RSS 置顶收录固定页、sitemap 自动+1;发布须双次全局重建 |
G10 ✅ |
这三篇完整演示"如何写一个自己的 Gmeek 插件",而不只是抄配置。
八、系列教程路线图
总揽即 roadmap。每完成一篇,这里会更新链接;状态图例:✅ 已发布 / ⏳ 计划中 / 💤 远期再说。
| 编号 | 教程 | 功能 | 类型 | 状态 |
|---|---|---|---|---|
| 前传 | 搭建全过程与原理 | 建站 | 教程 | ✅ |
| 前传 | 博客基础功能建设清单 | 规划 | 清单 | ✅ |
| G00 | 本文 | 全景调研 | 总揽 | ✅ |
| —— | 右侧文章目录插件 | GmeekTOC | 教程 | ✅ |
| G01 | 固定页面机制:做一个不进文章流的 About 页 | singlePage + iconList |
配置 | ✅ |
| G02 | 页脚装修:版权小字与"本站已运行 N 天" | bottomText + startSite |
配置 | ✅ |
| G03 | 给博客一张脸:自制 SVG favicon 与社交分享封面 | faviconUrl + ogImage |
配置 | ✅ |
| G04 | 把门牌号递给搜索引擎:RSS 直接当 sitemap 提交 | GSC / Bing / 百度 + sitemap_gen.py |
SEO | ✅ |
| G05 | 给文章图片装一盏灯:官方 lightbox 灯箱插件 | 官方插件 | 教程 | ✅ |
| G06 | 文章末尾的秘密:一行隐藏 JSON,给单篇文章开小灶 | 文章级配置 | 原理 | ✅ |
| G07 | 写作三件套:Alert 提示块、数学公式、Mermaid 图表 | 内置语法 + mermaid 三件套 | 教程 | ✅ |
| G08 | 自研插件(一):文章末尾的"上一篇 / 下一篇" | postList.json |
自研 | ✅ |
| G09 | 自研插件(二):标题下的字数与阅读时长 | DOM 统计 | 自研 | ✅ |
| G10 | 自研插件(三):凭空造出的时间线归档页 | singlePage + 数据渲染 |
自研 | ✅ |
| G11 | 运维两小件:robots.txt 与自定义 404 页 | static/ 直出 |
运维 | ✅ |
| G12 | 小补丁:外链自动新标签页打开 | URL 判定 + noopener | 自研 | ✅ |
| G13 | 数字分页条:借不到轮子,就自己造一个 | indexScript + Primer 内建分页样式 |
自研(社区方案失联) | ✅ |
| G14 | 手机上的文章目录:右下角 ☰ 与两个 TOC 插件的和平共处 | articletoc 适配 + 类名隔离/响应式分工 | 官方插件适配 | ✅ |
| G15 | Mermaid 翻车记:自动检测按需加载,顺手给 Gmeek 提个 PR | GmeekMermaid 自研插件 + 上游 #236/PR#319 | 自研 + 开源回馈 | ✅ |
| G16 | 目录会读心:把 tocbot 请到本地,让当前章节一路高亮 | CDN 资源本地化 + scrollspy | 进阶 | ✅ |
更新方式:每篇教程发布后,叶扬会回来编辑本文(Gmeek 监听 issue 的 edited 事件,编辑即自动重建),所以这张表会一直是最新的。
收官之后:候选选题池(G17 起)
正篇 G01–G16 收官,建设清单(前传 #4)也已回填,但清单并非一无所有。2026-09-15 盘出以下候选,按写作意愿排序:
| 候选 | 内容 | 依据 | 状态 |
|---|---|---|---|
| G17 SEO 收尾战 | 文章页补 <link rel="canonical">、JSON-LD(BlogPosting 结构化数据)、twitter:card;顺手清洁 meta description——框架当前直接取正文开头,会把 > 引用符和 [文字](链接) 语法原样塞进搜索摘要 |
#4 清单上仅剩的技术缺口(已 curl 实锤框架不自带) | 🎯 首选,随时可写 |
| 番外·收录实战 | G04 提交一周后,Google/Bing 真实收录数据对比、GSC"无法抓取"复查结论,回答"RSS 当 sitemap 到底有没有用" | G04、G16 结尾均已预告 | 📅 约 2026-09-21 后 |
| 候选·备份双保险 | 用 Actions 把 backup/ 定期镜像到私有仓库 |
#4 运维章自己提的建议 | 待定 |
| 候选·阅读进度条 | 文章顶部滚动进度条,G16 scrollspy 的姊妹篇 | 体验增强 | 选题偏薄,可能并入杂谈 |
| 候选·图片懒加载 | 正文 img 补 loading="lazy" |
#4 清单(灯箱做了、懒加载没做) | 本站每篇图极少,价值低 |
| 候选·跟版方法论 | Gmeek 版本升级流程、PR #319 合并后的跟踪与回馈闭环 | 运维 | 等上游合并后才有料 |
| ⏭️ 主动挂起 | 分享按钮、友链固定页、独立域名 + 百度收录 | #4 P2 | 有真实需求再说,不算欠债 |
参考资料汇总
- Gmeek 源码:https://github.com/Meekdai/Gmeek
- 官方进阶插件教程:https://blog.meekdai.com/post/%E3%80%90Gmeek-jin-jie-%E3%80%91-cha-jian-gong-neng-de-shi-yong.html
- 官方快速上手:https://blog.meekdai.com/post/Gmeek-kuai-su-shang-shou.html
- Primer CSS(GitHub 同源设计系统):https://primer.style/css
- utterances 评论系统:https://utteranc.es/
- tocbot 目录库:https://tscanlin.github.io/tocbot/
- Vercount 计数服务:https://vercount.one/
- 插件分享基地(issue #167):Meekdai/Gmeek#167
小结
调研结论可以浓缩成三句话:
- 配置层的红利还没吃完——About 页、版权声明、运行天数、favicon、分享封面全是一行配置的事,这是接下来 G01–G03 的内容;
- SEO 几乎零成本——RSS 直接当 sitemap 提交,robots/404 放静态目录即可;
- 真正有含金量的是自研三小件(上下篇、阅读时长、归档页),它们会逼出"如何写一个 Gmeek 插件"的完整方法论,那才是这个系列从"会用"走向"会造"的分水岭。
G01–G16 已全部完成,路线图正篇收官。接下来首选 G17 SEO 收尾战(canonical + JSON-LD + twitter:card + 清洁 description,把前传 #4 清单上仅剩的技术缺口清零);其后约 2026-09-21 是已承诺的 G04 收录实战番外——用 Google/Bing 的真实收录数据回答"RSS 当 sitemap 提交到底有没有用"。更远的候选见上方选题池。