我无比感谢我的母校
我无比感谢我的母校煤专。 四年前高考的失败,让我一度认为我会选择复读或者上专科。但煤专没有嫌弃我,依旧以不多不少的擦线本科分数收留了我,并让我顺利拿到法律意义上与其他本科地位平等的学士学位。可以说,如果没有四年前的网开一面,根本不会有如今的一切,更不用谈现在的工作。 我是一个笨拙的人,对于学习可以说一窍不通,旁人能够轻易记住的公式、题目我需要花大量时间和精力来去理解,这就造成了我考试的困难。以我的学习能力,可以说放在稍微好点的学校大概率会成为延毕的少数。但煤专心慈手软,理解我们的学习质量,得以在一次次的有惊无险和心照不宣中通过近百门课程,让我顺利毕业。 同时我也感谢遇到了不错的老师和同学,在大三大四各种压力接连不断之时,灵活调整课程安排来为我们的考前冲刺腾出时间,这些安排看起来好像不太会影响最后的结果,但多少让本就艰难的过程少些心累。同学也大多友善,谈不上深情厚谊,但也是相安平稳的度过了四年。 煤专也存在形式主义,但这种形式主义恰恰能给出巨大的操作空间————只要别太过分,面上事情做完,其余时间完全可以自主安排。大学四年我学习了摄影、投资、建博客甚至跑马拉松和健身,不敢说样样精通,但起
默契的告别
总是在火车上想起与她的故事。 从陌生相识到满眼欢喜,再到日后的沉默相对,用七年验证了一种轮回。 疯狂的岁月一去不复返。那段从生活谈到爱情,从过去谈到未来的日子真是让人怀念。那时我们天真且乐观的认为可以永远在一起,时间会改变一切不过是对本就不该发生故事的人的惩罚,我们会不一样。 但时间证明,没有什么不一样,没人跳的出无限的轮回与循环。 可我们仍然不死心,仍然坚信往日的美好可以冲破现实的禁锢,靠岁月往事来铺垫以后的未来。 于是540个日子过后,再次相约。前一夜难以入睡,很久不曾因为一个人而如此心潮起伏。不断的在想明天聊什么?说什么可以回忆起曾经? 曾经的见面,哪里需要这么多的顾虑,一条微信,能立刻不超过半小时内见到对方。现在只有无限的顾虑重重与边界清晰。 不出意外,现实依旧糟糕,开口没超过三句,就知道了今天是一场必定的告别。 吵架?不是。沉默?不是。有的只是无比正常的聊天,但再也不是以往那样的侃侃而谈,而是表面平静但内心充满负担的回应附和。这种平静要比冲突更加可怕,平静本身就是一种态度。这或许就是成年人最起码的体面,彼此都很默契的接话、回应,不让话掉在面前火苗正旺的烤炉。 离别的残忍,不在
Butterfly 建站笔记(一):从零搭建一个可折叠的更新记录页
博客维护一段时间后,页面样式、主题版本、导航结构和部署方式都会不断变化。如果这些修改只留在 Git 提交里,访客看不到,自己过几个月也很难快速回忆。于是我为 Butterfly 博客增加了一个独立的“更新记录”页面:它按年份折叠、按日期排列,并用不同颜色区分“新增、优化、修复、升级”等类型。 这篇文章不再只解释设计思路,而是从一个空页面开始,带你依次创建页面入口、YAML 数据、Hexo 渲染脚本和 CSS 样式。完成后,你会得到一个固定地址为 /updates/、可以长期维护的更新记录页。 下面的交互演示器用于直观呈现“文件怎样逐步增加、页面怎样逐步成形”。它不会在浏览器中真正运行 Hexo;真正的生成与检查仍需在 Hexo 项目目录执行本文给出的命令。 点击演示器中的“上一步”“下一步”或左侧步骤,可以从空白页面一直看到最终时间线。右上角还可以切换桌面/手机宽度和浅色/深色预览。 整个功能由四个核心文件组成: 它们之间的关系很简单:updates.yml 保存内容,blog-updates.js 把内容转换成 HTML,blog-updates.css 负责外观
Butterfly 建站笔记(二):从零搭建分类与标签内容地图
Butterfly 默认的分类页和标签页可以列出名称与文章数量,但很难直接回答“这个分类最近写了什么”“某个标签经常和哪些标签一起出现”“能不能在当前页面搜索与排序”。本篇将从默认列表开始,一步一步把分类与标签改造成一张内容地图。 完成后,分类总览会显示说明、图标、颜色、最近文章和十二个月活跃度;标签总览会支持即时搜索、热度排序、最近使用排序和关联标签;分类与标签详情页也会获得统一的文章列表和横向导航。 交互演示负责展示文件与页面如何逐步变化,并不会在访客浏览器中执行 Hexo。真实数据统计仍在 hexo generate 阶段完成。 本次改造包含四个核心文件: 先确认分类页和标签页已经存在: 它们通常分别包含: 在修改前执行一次: 保证原有分类、标签和详情页能够正常生成。不要直接修改 public/categories/、public/tags/ 或主题依赖中的模板。 Hexo 知道分类名称和文章数量,却不知道“建站笔记应该使用代码图标和蓝色”。在 source/_data 中新建 taxonomy.yml: 字段含义如下: 普通标签不需要写进 YAML,它们仍然从文章 Front
Butterfly 建站笔记(三):从零重做可搜索、可折叠的文章归档
Butterfly 默认归档能够按时间显示文章,但文章变多后会遇到三个问题:分页把完整时间线切开、无法在当前页搜索全部文章、年份和月份缺少统一的折叠与数量反馈。本篇从关闭归档分页开始,逐步建立年份、月份、稳定编号、全文筛选和随机阅读。 本文只接管 /archives/ 主归档页。年度归档、月度归档、分类和标签分页继续由 Hexo 原生成器处理。 项目文件分工如下: 打开站点 _config.yml,找到归档生成器配置: per_page: 0 的作用是让主归档页面在构建时拿到全部文章。若仍保留每页十篇,浏览器端搜索只能搜索当前分页,无法实现真正的完整归档。 修改后执行: 确认 /archives/ 中已经包含全部文章,再继续编写接管脚本。 新建 scripts/blog-archives.js,先写基础工具: 过滤器中要严格限制页面: 这样 /archives/2026/ 和 /archives/2026/07/ 不会被重复接管。 文章日期可能来自不同环境。如果构建服务器使用 UTC,本地使用上海时区,临近午夜的文章可能被分进不同月份。站点 _config.yml 应设置: 格式化时优
Butterfly 建站笔记(四):从零搭建 ECharts 博客统计页
文章数量、标签热度和分类分布都存在于 Hexo 数据中,但普通页面无法直观看出发布节奏。本篇从一个空白 /charts/ 页面开始,在构建阶段统计月份、标签和分类,再使用站内 ECharts 生成折线图、横向柱状图和分类图。 在博客根目录安装: 确认 package.json 和 package-lock.json 都发生变化。不要只引用公共 CDN,否则离线预览、国内网络和第三方可用性都会成为额外故障点。 新建 source/charts/index.md: 统计页拥有固定地址,不会进入首页文章列表。 新建 scripts/blog-charts.js: 这一步只把 Hexo 查询集合转成普通数组,后续统计才不会依赖内部实现。 先累计实际出现的月份: 只有这一步还不够。如果某个月没有文章,它会直接从横轴消失。需要根据最早和最晚文章建立连续月份: 最终得到: 第二排序条件很重要:文章数相同的标签按中文名称稳定排序,避免每次构建顺序变化。 分类可能有父子关系,不能只把它当作一维数组: 如果只需要扁平玫瑰图,也可以把叶子节点展开后统计;保留树结构则可以使用旭日图展示上下级关系。 不要直接把
Butterfly 建站笔记(五):从零实现 Eurkon 风格文章头部
Eurkon 风格文章头部的吸引力来自封面主色、标题层级、分类标签和动态波浪,但直接迁移整套主题会与现有 Butterfly 定制发生大量冲突。本篇采用“增强层”方案:保留 Butterfly 原模板,在构建期只给文章页注入资源,再由浏览器重组现有 DOM。 这不是完整 Eurkon 主题迁移,也不修改 node_modules/hexo-theme-butterfly/。以后升级 Butterfly 时,站点级增强文件仍然独立存在。 不要编辑: 依赖升级会覆盖这里的修改。我们只读取 Butterfly 已经生成的结构,例如: 新建 scripts/post-header-effect.js: 这样分类页、标签页和普通独立页不会加载文章头部资源。 新建 source/js/post-header-eurkon.js: data-eurkon-bound 防止 PJAX 多次进入文章时重复添加封面和波浪。 不要重新生成另一套标题,而是移动原节点: 真实站点中,分类和标签选择器要根据当前 Butterfly 输出确认。若找不到某个节点,跳过即可,不要让整个标题消失。 背景图不方便做取色、解
Butterfly 建站笔记(六):从零搭建稳定的首页摄影轮播
Butterfly 的 index_img 适合一张首页背景,但摄影博客往往希望轮换多张作品。简单定时修改 background-image 会出现蓝色空档、坏图卡死、切回后台标签后突然连跳,以及线上缓存仍执行旧代码等问题。本篇从保留默认图开始,逐步实现预加载、双图层交叉淡入和缓存版本管理。 打开 _config.butterfly.yml: 不要把默认图删掉。轮播 JavaScript 未加载、配置为空或所有图片失败时,它仍是可见背景。 在同一配置文件加入: 建议切换间隔不少于 5 秒,过快会分散阅读注意力,也增加图片请求频率。 新增图片时先保留上一张已经验证可用的图,确认新图正常加载后再删除旧图。 浏览器无法直接读取 YAML。新建 scripts/home-banner-config.js: 只向首页写入数据: 不要把轮播配置注入每一篇文章。 新建 source/js/home-banner-carousel.js: 为什么不用一个元素直接换背景?因为浏览器需要下载并解码新图。单层在这个间隙可能露出 Butterfly 原背景色;双层可以让旧图持续可见。 样式可以放进 sourc
Butterfly 建站笔记(七):从零搭建可回滚的 GitHub Actions 部署
Hexo 自动部署不只是“构建后把 public 复制到服务器”。如果直接覆盖正式目录,上传中断、两个工作流并发或构建产物不完整,都可能让线上网站进入半更新状态。本篇从源码仓库开始,逐步建立依赖锁定、构建验证、临时上传、部署锁、备份激活和缓存排查。 本文中的服务器用户名、地址和目录都是示例。SSH 私钥必须保存到 GitHub Secrets,不要写进仓库、文章或日志。 不要在服务器正式目录中直接运行 Hexo,也不要把服务器目录当作源码仓库。 package.json 至少提供: 提交 package-lock.json,并在本地验证: npm ci 严格按照锁文件安装;依赖声明与锁文件不一致时直接失败,比自动修改依赖树更适合 CI。 只检查 hexo generate 退出码不够。可以在 tools/verify-build.mjs 检查: 项目还可以继续验证本地 JS/CSS 引用、空白页面、关键自定义模块和构建日志中的 ERROR、FATAL。 新建 .github/workflows/deploy.yml: concurrency 防止两个提交同时激活不同版本,但服
Butterfly 建站笔记(八):从零搭建旅行相册足迹地图
普通相册只能回答“拍了什么”,地图则能回答“去过哪里”。本篇从一份 gallery.yml 开始,把省份、城市、坐标、影集页面与照片数量组织成统一数据,再使用 MapLibre 显示去过的行政区和城市点位。即使地图加载失败,访客仍能通过下方影集入口浏览照片。 地图是相册的导航层,不是相册本身。照片仍由静态页面和灯箱承载,避免外部地图服务失败时整个相册不可用。 项目构建时从依赖复制 MapLibre 发布文件到: 不要长期依赖远程 JS/CDN。地图底图和行政区 GeoJSON 可以来自外部,但运行库本身应尽量由站点控制。 新建或编辑 source/_data/gallery.yml: admin_geojson 中的 {adcode} 会在浏览器端替换为省、市、区县行政代码。 字段说明: marker_offset 只在两个点位过近时使用,不要通过随意修改真实坐标来避免重叠。 父影集使用 children 指向城市影集,地图和影集导航都从这里读取关系。 source/gallery/index.md: 这个标签负责输出英雄区、地图容器、视图切换和根影集导航










