2026.05.26 (二)

✨ GPT-5.5 的摘要  

博客重启后,我在 sidebar 加上文章日历和分类活动统计,并做出以当前文章为基准的月份显示和月度归档探索。

整理完 /devlog/github-pages-blog/github-pages-blog-restart-system/ 之后,马上看到了下一个问题。

文章又开始写了。可是博客重新活过来的感觉还不够。只靠分类列表,很难看出这个博客什么时候动过、哪一天留下了记录、最近有什么流向。

要重新写 Daily Review,日期感很重要。

这个博客的中心,终究是“哪一天留下了什么”。可是 GitHub Pages 博客不像 Naver Blog 那样,自然就有可见的日期探索。因为是静态博客,更需要自己做出来。

所以今天晚上接上的功能,不只是简单装饰。

这是把 sidebar 从文章列表的辅助装饰,改造成展示日期和活动流向的探索工具。

最先接上的是小而直接的日历

第一个提交是 f6971fc

f6971fc  feat: add sidebar activity widgets

那时新建的文件有两个。

_includes/sidebar-calendar.html
_includes/sidebar-nav-stats.html

我在 sidebar.html 里接上了日历 include。

<section class="sidebar-calendar"
  data-sidebar-calendar
  data-calendar-lang="zh-Hans"
  data-calendar-posts-src="/assets/data/calendar-posts-zh-Hans.json"
  data-calendar-weekdays="[&quot;日&quot;,&quot;一&quot;,&quot;二&quot;,&quot;三&quot;,&quot;四&quot;,&quot;五&quot;,&quot;六&quot;]"
  data-calendar-label-suffix="文章日历"
  data-calendar-post-count-label="篇"
  data-calendar-post-list-label="文章"
  data-initial-month="2026-05"
  data-focus-date="2026-05-26"
  data-current-path="/zh-Hans/devlog/github-pages-blog/github-pages-blog-sidebar-calendar/"
  data-min-month="2024-12"
  data-max-month="2026-06"
  aria-label="2026.05 文章日历">
  <div class="sidebar-calendar__archive" data-calendar-archive aria-label="按年和月份统计文章数">
    <div class="sidebar-calendar__years" data-calendar-years></div>
    <div class="sidebar-calendar__months" data-calendar-months></div>
  </div>
  <div class="sidebar-calendar__grid" data-calendar-grid>
      <span class="sidebar-calendar__weekday">日</span>
      <span class="sidebar-calendar__weekday">一</span>
      <span class="sidebar-calendar__weekday">二</span>
      <span class="sidebar-calendar__weekday">三</span>
      <span class="sidebar-calendar__weekday">四</span>
      <span class="sidebar-calendar__weekday">五</span>
      <span class="sidebar-calendar__weekday">六</span>
        <span class="sidebar-calendar__day sidebar-calendar__day--blank" aria-hidden="true"></span>
        <span class="sidebar-calendar__day sidebar-calendar__day--blank" aria-hidden="true"></span>
        <span class="sidebar-calendar__day sidebar-calendar__day--blank" aria-hidden="true"></span>
        <span class="sidebar-calendar__day sidebar-calendar__day--blank" aria-hidden="true"></span>
        <span class="sidebar-calendar__day sidebar-calendar__day--blank" aria-hidden="true"></span>
      <span class="sidebar-calendar__day"><span class="sidebar-calendar__day-number">1</span></span>
      <span class="sidebar-calendar__day"><span class="sidebar-calendar__day-number">2</span></span>
      <span class="sidebar-calendar__day"><span class="sidebar-calendar__day-number">3</span></span>
      <span class="sidebar-calendar__day"><span class="sidebar-calendar__day-number">4</span></span>
      <span class="sidebar-calendar__day"><span class="sidebar-calendar__day-number">5</span></span>
      <span class="sidebar-calendar__day"><span class="sidebar-calendar__day-number">6</span></span>
      <span class="sidebar-calendar__day"><span class="sidebar-calendar__day-number">7</span></span>
      <span class="sidebar-calendar__day"><span class="sidebar-calendar__day-number">8</span></span>
      <span class="sidebar-calendar__day"><span class="sidebar-calendar__day-number">9</span></span>
      <span class="sidebar-calendar__day"><span class="sidebar-calendar__day-number">10</span></span>
      <span class="sidebar-calendar__day"><span class="sidebar-calendar__day-number">11</span></span>
      <span class="sidebar-calendar__day"><span class="sidebar-calendar__day-number">12</span></span>
      <span class="sidebar-calendar__day"><span class="sidebar-calendar__day-number">13</span></span>
      <span class="sidebar-calendar__day"><span class="sidebar-calendar__day-number">14</span></span>
      <span class="sidebar-calendar__day"><span class="sidebar-calendar__day-number">15</span></span>
      <span class="sidebar-calendar__day"><span class="sidebar-calendar__day-number">16</span></span>
      <span class="sidebar-calendar__day"><span class="sidebar-calendar__day-number">17</span></span>
      <span class="sidebar-calendar__day"><span class="sidebar-calendar__day-number">18</span></span>
      <span class="sidebar-calendar__day"><span class="sidebar-calendar__day-number">19</span></span>
      <span class="sidebar-calendar__day"><span class="sidebar-calendar__day-number">20</span></span>
      <span class="sidebar-calendar__day"><span class="sidebar-calendar__day-number">21</span></span>
      <span class="sidebar-calendar__day"><span class="sidebar-calendar__day-number">22</span></span>
      <span class="sidebar-calendar__day"><span class="sidebar-calendar__day-number">23</span></span>
      <span class="sidebar-calendar__day"><span class="sidebar-calendar__day-number">24</span></span>
      <span class="sidebar-calendar__day"><span class="sidebar-calendar__day-number">25</span></span>
      <span class="sidebar-calendar__day sidebar-calendar__day--focus"><span class="sidebar-calendar__day-number">26</span></span>
      <span class="sidebar-calendar__day"><span class="sidebar-calendar__day-number">27</span></span>
      <span class="sidebar-calendar__day"><span class="sidebar-calendar__day-number">28</span></span>
      <span class="sidebar-calendar__day"><span class="sidebar-calendar__day-number">29</span></span>
      <span class="sidebar-calendar__day"><span class="sidebar-calendar__day-number">30</span></span>
      <span class="sidebar-calendar__day"><span class="sidebar-calendar__day-number">31</span></span>
  </div>
  <section class="sidebar-calendar__post-list sidebar-calendar__post-list--dynamic" data-calendar-post-list aria-live="polite" hidden></section>
</section>

最初的日历没有 JavaScript,只用 Liquid 做出来。

site.posts 里排除隐藏文章,然后计算当前月份的第一天星期几和最后一天日期。连 2 月闰年计算也在 Liquid 里处理。




月份里有文章的日期会变成链接,没有文章的日期只保留数字。最初的基准是 site.time。也就是说,这个阶段的日历,是展示“当前月份文章状况”的 sidebar widget。

即使只做到这个程度,效果也马上出现了。

博客重新开始活动的感觉出来了。和只看文章标题列表不同,日历会显示记录的密度。哪几天文章集中,哪一天空着,今天在哪里,一眼就能看到。

也给分类接上活动信息

只接日历可以看到日期流向,但各分类的流向仍然很迟钝。

所以我也一起做了 sidebar-nav-stats.html

这个 include 把 sidebar 项目的 URL 看作分类路径,再重新筛选属于该分类的文章。



比如 /daily-review 会显示 daily-review 分类的文章数,/diary/ai 则只留下同时包含 diaryai 的文章。

输出很简单。

文章数 · 最近文章日期

我喜欢这一点,是因为 sidebar 从单纯目录里脱出来了。

可以看到 今天这一天 有几篇,人工智能 文章最近什么时候更新,GitHub Pages Blog 是否真的还在运营。一个博客是死着还是活着,比起文章数量,最近日期更能说明问题。

立刻先调整移动端密度

日历一接上,移动端密度马上成了问题。

sidebar 在桌面端还有余裕,但在移动端会下沉到正文下面,或者和菜单混在一起。如果日历格子太大,文章数标签又太长,一个 widget 就会吃掉太多屏幕。

所以我在 17d074db401d8b 里马上缩紧了 sidebar 活动标签和日历密度。

17d074d  fix: tighten sidebar activity labels
b401d8b  [Fix] | Sidebar calendar: Improve mobile density

SCSS 里把日期格子固定为 aspect-ratio: 1,并用了小字号和 4px radius。分类活动信息也做成在一行里小小显示。

这里重要的是不要让日历变成“主角”。

日历是帮助博客探索的装置。它不能比正文还大。尤其是记录型博客里,sidebar 要提供信息,但不能妨碍阅读文章。

改成以当前文章为基准的月份

很快,更重要的问题出现了。

如果日历以 site.time 为基准,那么读 2025 年的文章时,也会出现 2026 年 5 月的日历。这样日历就无法说明当前文章的语境。

所以我在 ccb58d5 里改了基准日期。

ccb58d5  [Fix] | Sidebar: Refine calendar behavior

核心是这一段。



如果页面有 date,就显示那一天所属的月份。没有日期的页面则照旧使用 site.time

这个修改改变了日历的性质。

最初的日历是“这个月的博客状况”。现在它变成了“当前正在阅读的文章所在的时间”。读过去的 Daily Review 时,可以看到那个月的记录流向,也能继续找到同一个月里还有哪些文章。

这对以日期为中心的记录博客更合适。

同一天多篇文章时展开成列表

同一个提交里,我也接上了按日期分组的文章列表。

如果一天只有一篇文章,日期直接链接到那篇文章就可以。但如果一天有多篇文章,就会出现问题。只看重启第一天,也有 Daily Review 和 AI 对话归档在同一天。

所以文章数量超过一篇的日期,不再直接跳到某篇文章,而是移动到那一天的文章列表。

<section id="sidebar-calendar-2026-05-25-posts" class="sidebar-calendar__post-list">
  <h4 class="sidebar-calendar__post-list-title">5月25日文章</h4>
  <ul>
    ...
  </ul>
</section>

这个阶段的规则很简单。

1 篇文章:跳到该文章
2 篇以上:跳到那一天的文章列表

这并不是完美规则,而是先解决当前同一天多篇文章问题的方法。但重要的是没有把问题藏起来。

一个日期上可能有多篇文章,系统必须承认这一点。如果 Daily Review、AI 对话、开发记录会在同一天出现,这个处理就是必要的。

也接上了 JavaScript enhancement

只靠 Liquid 日历,可以做到以当前月份为中心的探索,但跨月份探索不方便。

所以我在 b06b6d6 里接上了 JavaScript。

b06b6d6  [Feat] | Sidebar calendar: Add archive navigation

新文件是这个。

assets/js/custom/sidebar-calendar.js

并且注册到 _config.ymlafter_footer_scripts

after_footer_scripts:
  - /assets/js/custom/dark-theme.js
  - /assets/js/custom/sidebar-calendar.js

Liquid 侧把文章数据作为 JSON 传给页面。

<script type="application/json" data-calendar-posts>
[
  {
    "title": "...",
    "url": "...",
    "date": "2026-05-25"
  }
]
</script>

JavaScript 读取这份数据,生成 postsByDatepostCountByMonthpostCountByYearlatestPostMonthByYear。然后渲染上一个月/下一个月按钮、month input、按年/月显示文章数的按钮,以及按日期动态出现的文章列表。

这个结构不错,是因为没有丢掉 fallback。

有 JavaScript 时,月份移动和归档探索会变方便。没有 JavaScript 时,Liquid 也已经渲染了当前文章基准月份和同一天多篇文章的 fallback 列表。

在静态博客里,这个平衡很重要。

今天改变了什么

今天夜里到凌晨的流程是这样的。

f6971fc  添加 sidebar 日历和分类活动统计
17d074d  调整 sidebar 活动标签密度
b401d8b  调整移动端日历密度
ccb58d5  处理当前文章基准月份和同一天多篇文章列表
b06b6d6  添加用于月度归档探索的 JavaScript enhancement

核心文件是这些。

_includes/sidebar.html
_includes/sidebar-calendar.html
_includes/sidebar-nav-stats.html
assets/js/custom/sidebar-calendar.js
_sass/custom/customOverride.scss
_config.yml

一句话概括就是这样。

给博客的 sidebar 接上展示日期和分类活动流向的探索层。

结果

现在博客 sidebar 不再只是简单的分类列表。

它会显示当前文章所在的月份,标出有文章的日期,同一天有多篇文章时展开成列表。分类项目也带着文章数和最近文章日期。JavaScript 开启时,还可以在年份和月份之间来回查看博客归档。

从作品集角度看,这次工作的重点在于不用服务器也提高了可探索性。

没有单独 DB,也没有 API。只用 Jekyll 的 site.posts、Liquid、SCSS 和一小段 JavaScript,就补上了静态博客的弱点。记录拥有日期。把日期显示在 UI 上之后,博客就不再只是文章堆,而像一个按时间移动的系统。

今天接上的日历,就是这个开始。

留下评论