Building my personal website with Jekyll
这篇文章记录我的个人博客网站从基础主题到自定义架构的搭建过程。它并不是一篇从零开始的 Jekyll 教程,而是对本站整体结构、功能设计和若干关键改造经验的总结。
本站基于 Jekyll 和 Minimal Mistakes 主题构建。Jekyll 负责将 Markdown 文件、Liquid 模板和静态资源编译为可部署的静态网站;Minimal Mistakes 提供了较完整的页面布局、导航、归档、搜索、侧边栏和文章模板。在此基础上,我主要做了三类工作:一是调整网站结构,使其更符合个人主页和学术博客的使用场景;二是增加主题切换、写作热力图、交互地图等功能;三是优化页面样式和交互细节,使网站在浅色和深色模式下都能保持一致的视觉体验。
1. 整体架构
网站的基本结构仍然遵循 Jekyll 的标准组织方式。全局配置由 _config.yml 控制,页面内容主要由 Markdown 文件维护,布局结构则由 _layouts 和 _includes 中的 Liquid 模板负责。静态资源如 CSS、JavaScript、图片、GeoJSON 数据等统一放在 assets 目录下。
从渲染逻辑上看,网站可以分为三层。
第一层是全局页面框架。default.html 是最外层布局,负责组织网页的基本结构,包括 <head>、顶部导航栏、正文容器、搜索区域、页脚和脚本加载。它相当于整个网站的骨架,所有页面最终都会嵌入到这一结构中。
第二层是内容页面布局。single.html 负责文章页和普通页面的主要排版,包括标题、日期、分类标签、正文、侧边栏、上一篇/下一篇文章以及评论模块。这一层决定了单篇内容如何被展示。
第三层是局部组件。head.html、masthead.html、footer.html 等文件分别管理页面头部资源、顶部导航栏和页脚信息。这样的拆分方式使网站结构更清晰,也便于后续单独修改某个模块,而不影响整体布局。
整体上,本站采用的是“配置控制全局、模板控制结构、Markdown 控制内容、assets 控制资源”的架构。
2. 页面布局和设计
网站页面的核心布局基于 Minimal Mistakes 的 single 页面模式。主页、普通页面和博客文章都可以通过 front matter 指定布局、标题、摘要、固定链接、头图和侧边栏等信息。
例如,主页使用 layout: single,并通过 permalink: / 指定为网站首页。头部区域可以设置 overlay_image 和 overlay_filter,用于生成带渐变遮罩的首页视觉背景。正文部分则直接使用 Markdown 与 HTML 结合的方式组织内容,使个人介绍、教育经历、论文列表、热力图和地图等模块可以放在同一页面中。
顶部导航栏是网站交互的核心入口。它包括站点标题、导航链接、搜索按钮和主题切换按钮。导航链接来自站点数据文件,便于集中维护;搜索按钮仅在开启站内搜索时显示;主题切换按钮被放在导航栏右侧,可以直接在浅色和深色模式之间切换。
页脚则保留了社交链接、RSS feed、版权信息和网站构建信息。相比正文区域,页脚功能较稳定,因此主要保持主题原有结构,只做必要的样式适配。
3. 主题切换
本站的一个重要改造是加入了浅色和深色模式切换功能。它的核心思路不是为每个页面单独写一套样式,而是在 HTML 根元素上维护一个统一的主题状态。
当点击导航栏中的主题切换按钮时,脚本会读取当前的 data-theme 属性。如果当前是 dark,则切换为 light;如果当前是 light,则切换为 dark。新的主题状态会写入 localStorage,这样下次访问网站时仍然可以保留之前的选择。
这一设计的好处是,主题状态可以被整个页面共享。CSS 可以通过 [data-theme="dark"] 或 [data-theme="light"] 定义不同的颜色变量;JavaScript 组件也可以读取当前主题,并动态更新自己的显示效果。
更重要的是,主题切换不只影响文字和背景颜色,还会同步影响热力图、地图底图等动态组件。这样可以避免出现页面主体已经切换到深色模式,但图表或地图仍然停留在浅色样式的问题。
4. 码字热力图
主页中加入了一个年度写作热力图,用来展示不同日期的写作字数。这个功能借鉴了 GitHub contribution graph 的形式,但统计对象不是代码提交,而是博客文章的写作量。
热力图的数据来自 /api/posts.json。页面加载后,脚本会读取文章数据,并按日期汇总每日写作字数。随后,根据当前年份生成完整日期序列,将每天的字数映射到日历网格中。
这个模块有几个设计重点。
首先,它不是静态图片,而是基于 ECharts 动态生成。这样可以根据真实文章数据自动更新,不需要手动维护图表。
其次,颜色分级不是固定的,而是根据当年最大单日写作量动态计算。这样可以避免在写作量较少或较多时图例失衡。
第三,热力图会响应主题切换。浅色模式下使用较亮的背景和紫色渐变;深色模式下则切换为更适合暗背景的色阶。主题变化时,脚本会重新构建图表配置,并刷新显示效果。
这个模块的作用不仅是装饰首页,也为网站增加了一种自我记录功能。它把博客从单纯的文章展示空间,变成了一个可以观察写作习惯和内容积累过程的个人仪表盘。
5. 交互地图
主页的另一个自定义模块是交互式地图。地图基于 Leaflet 实现,用于展示我去过或与个人经历有关的城市,并通过连线表达城市之间的联系。
地图数据主要来自 GeoJSON 文件。页面加载后,脚本会读取 /assets/data/cities.geojson,将其中的点要素渲染为地图标记。每个点可以绑定城市名称弹窗,并使用自定义 SVG 图标。
除了城市点位,地图还手动定义了一组城市之间的连接关系。脚本根据城市名称查找对应坐标,并使用 L.polyline 绘制连线。这种设计方式比较灵活,适合表达个人移动经历、研究区域联系,或城市网络关系。
地图也支持主题同步。浅色模式下使用 CARTO light 底图,深色模式下使用 CARTO dark 底图。当切换网站主题时,地图会移除当前底图并加载对应的新底图。这样,地图不会在深色页面中显得突兀。
6. 设计逻辑
这些新功能并不是孤立添加的,而是围绕个人学术网站的使用需求展开。
第一,网站需要承担个人主页功能。因此首页不仅展示个人简介,还包括教育经历、论文列表、写作统计和地图。这些内容共同构成了一个更完整的个人学术档案。
第二,网站需要承担博客记录功能。因此文章系统仍然以 Markdown 为核心,保留 Jekyll 的分类、标签、归档和本地预览流程。写作内容可以直接通过 Markdown 维护,降低长期更新成本。
第三,网站需要承担可视化展示功能。热力图和地图都不是普通文本内容,而是将个人写作活动和空间经历以可视化方式呈现。这使网站更接近一个轻量级的个人数据展示平台。
第四,网站需要有一致的视觉系统。主题切换功能不仅影响页面文字和背景,也影响图表、地图、按钮、导航栏和链接状态。相比简单地反转颜色,这种方式更强调不同组件之间的协调。
7. 总结
这个网站的搭建过程可以概括为:以 Jekyll 和 Minimal Mistakes 提供基础结构,再通过自定义布局、样式和 JavaScript 功能,把它改造为一个更符合个人需求的学术博客。
它的核心架构仍然是静态网站,但在静态框架中加入了一些动态交互模块:主题切换负责统一视觉状态,写作热力图负责记录内容生产,交互地图负责展示空间经历,Markdown 文章系统负责长期内容维护。
对我来说,这个博客不仅是一个展示个人信息和研究成果的网页,也是一个持续记录研究、学习和技术实践的工具。相比使用现成模板,自己理解并调整网站架构的过程更重要。它让我能够清楚地知道每个功能放在哪里、如何工作,以及未来需要扩展时应该从哪里修改。
Leave a comment