G02 页脚装修:版权小字与"本站已运行 N 天"

上一期 G01 搞定了 About 页,博客终于能回答"你是谁"。但叶扬低头看了一眼页脚——光秃秃一个年份加 Powered by Gmeek,像刚交钥匙的毛坯房。这期给它添两样小东西:文章末尾的版权小字,和那个很多老博客都有的"本站已运行 N 天"。全程只改 config.json,不写一行代码。

最终效果

先看成品,就在你现在这篇文章的右下角和页面最底部:

配置:就两行

打开仓库根目录的 config.json,加上:

{
    "startSite": "09/13/2026",
    "bottomText": "✍️ 原创文章,转载请注明出处~叶扬谢谢你来过 ❤️"
}

改完老规矩——config.json 的改动不触发自动构建,手动跑一次全局重建:

gh workflow run "build Gmeek"

约一分钟,收工。

bottomText 到底出现在哪

很多人(包括叶扬)第一反应是:这行字该在页脚吧?

不在。看模板 post.html:72,它紧跟在正文 #postBody 的后面,还是右浮动:

<div id="postBody"><!-- 文章正文 --></div>
<div style="font-size:small;margin-top:8px;float:right;">
  {{ blogBase['bottomText'] }}
</div>

所以它的真实位置是每篇文章正文的右下角、评论按钮的上方——正好是读者读完准备划走时目光落的位置。版权声明放这里,比放页脚有效得多。

两个容易疑惑的行为,源码里都有答案:

  1. 首页和列表页看不到它。 bottomText 只在文章模板 post.html 里渲染,列表页模板 plist.html 压根没有这个变量。
  2. About 等固定页也看不到它。 Gmeek.py:197 里写得很直白:识别到 singlePage 时 postBase["bottomText"]=''——框架主动把它清空了。想想也合理:"转载请注明出处"挂在自我介绍页确实莫名其妙。

"运行 N 天"是怎么算出来的

机制在 footer.html,一个十几行的内联脚本:

if("{{ blogBase['startSite'] }}"!=""){
    var startSite=new Date("{{ blogBase['startSite'] }}");
    var diff=now.getTime()-startSite.getTime();
    var diffDay=Math.floor(diff/(1000*60*60*24));
    document.getElementById("runday").innerHTML="网站运行 "+diffDay+" 天"+" • ";
}

构建时模板把日期字符串填进去,剩下的计算发生在每个访客的浏览器里。所以它不需要服务器、不需要定时任务,打开页面的瞬间现算,N 永远是最新的。

中文文案"网站运行 / 天"来自 Gmeek.py:20i18nCN 字典;英文版是 run / day(s),俄语版也有。把 config.json 里的 "i18n" 改成 ENRU 能切换。

踩坑预警:日期千万别写 2026-09-13

这是本期最值得停下来看的一段。叶扬一开始本能地想把日期写成 ISO 格式 "2026-09-13",顺手在 Node 里做了个实验:

new Date('2026-09-13')   // Sun Sep 13 2026 08:00:00 GMT+0800(中国标准时间)
new Date('09/13/2026')   // Sun Sep 13 2026 00:00:00 GMT+0800(中国标准时间)

看出区别了吗:

这个 8 小时的时差会闹出喜剧效果:建站第一天,如果有读者在早上 8 点之前访问,now - startSite 算出来是负数,Math.floor 一取整——

网站运行 -1 天

一个还没出生就已经运行了一天的网站,赛博玄学。官方作者用的 "02/16/2015" 正是美式斜杠格式(月/日/年),看起来随意,其实是唯一安全的写法。照抄这个格式就对了。

顺带认识一下邻居:filingNum

翻页脚模板时还会看到一个配置项 filingNum,填上 ICP 备案号后会显示在页脚并自动链接到工信部备案系统:

{%- if blogBase['filingNum']!='' -%}
<span id="filingNum"><a href="https://beian.miit.gov.cn/">{{ blogBase['filingNum'] }}</a></span>
{%- endif -%}

这是国内绑定自定义域名、完成备案后才用得上的东西。GitHub Pages 的免费域名碰不到备案,先知道有这扇门就行,钥匙以后再说。

一个时序小插曲

最后分享一个和框架无关、但叶扬真实踩到的坑:把配置 git push 之后立刻触发全局重建,那一次构建 checkout 到的居然还是旧配置,页面什么都没变。

原因是 push 的 ref 更新与 workflow 调度之间存在短暂竞态,dispatch 抢在了新提交生效的前一秒。重新触发一次构建即恢复正常。教训写进操作手册:push 之后深呼吸几秒,再 gh workflow run,急不得。

验证清单

小结

Gmeek 的配置项像宜家家具:零件都给你切好了,拧上螺丝就行。bottomTextstartSite 一个管"文章的尾巴",一个管"站点的年龄",两行配置,博客立刻从"样板间"有了点"自己家"的味道。

下一期 G03,搞点面子工程:favicon 和社交分享封面 ogImage——让博客出现在浏览器标签页和聊天框里时,不再是灰扑扑的默认图标。

参考

✍️ 原创文章,转载请注明出处~叶扬谢谢你来过 ❤️