前言

把看过的电影、书和其他作品放到一个页面里,封面、评分和日期从 YAML 读取。这个页面原来叫“人生足迹”,后来改成了现在的“藏宝阁”。

美化之前

本站使用 Hexo 6.0.0 + Butterfly 4.5.1,其他版本请按实际情况调整。样式、脚本引入及全局变量用法可参考:

参考链接

  • 亦封《重构记录 - 4》(足迹页部分):https://meuicat.com/blog/42/(原链接暂不可用)。

修改方案

1. 创建页面

新建 source/collect/index.md:

1
2
3
4
5
6
7
8
9
---
title: 藏宝阁
date: 2026-11-11 17:00:00
type: collect
top_img: false
aside: false
---

记录看过的作品。

顶栏 Banner 是已有的独立教程,这里不作为收藏卡片的前提。

2. 准备数据

新建 source/_data/collect.yml。以下条目选自本站现有数据,日期是观看记录,不是程序推断的作品上映日期。

1
2
3
4
5
6
7
8
9
10
- class_name: 📽️ 电影
class_desc: 看过以后留下的一点记录
link_list:
- name: 罗小黑战记
score: 5
premiere: 推荐
icon: fa-solid fa-film
time: 2026/06/12
img: https://img.june-pj.cn/img/2026/06/luoxiaoheizhanji.webp
link: https://movie.douban.com/subject/26709258/

premiere 在这套数据里是“推荐、已看”一类展示标签,字段名沿用历史结构,不代表上映时间。score 按五分制处理。

3. 星级辅助函数

新建 scripts/collect-stars.js,已有 toStar helper 就选择替换原实现或保留原实现,不要重复注册两份。下面这版代码会把分值限制到 0~5:

1
2
3
4
5
6
7
8
hexo.extend.helper.register('toStar', function (value) {
const score = Math.max(0, Math.min(5, Number(value) || 0));
const whole = Math.floor(score);
const half = score > whole ? 1 : 0;
return '<i class="fa-solid fa-star" style="color:#FFD43B"></i>'.repeat(whole)
+ (half ? '<i class="fa-solid fa-star-half-stroke" style="color:#FFD43B"></i>' : '')
+ '<i class="fa-regular fa-star" style="color:#FFD43B"></i>'.repeat(5 - whole - half);
});

4. 添加模板分支

在 themes/butterfly/layout/page.pug 的 case page.type 内追加:

1
2
when 'collect'
include includes/page/collect.pug

随后新建 themes/butterfly/layout/includes/page/collect.pug:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#article-june-collect
.june-collect
!= page.content
if site.data.collect
each group in site.data.collect
h2= group.class_name + ' (' + group.link_list.length + ')'
if group.class_desc
.june-collect-desc= group.class_desc
.june-collect-list
each item in group.link_list
.june-collect_box(title=item.name style=item.img ? 'background-image:url(' + item.img + ')' : '')
.june-collect_top
i(class=item.icon || 'fas fa-film')
span= item.premiere || '已看'
.june-collect_content
span= item.name
div!= toStar(Number(item.score) || 0)
p= item.time
if item.link
.june-collect-div
a.june-collect-a(href=item.link target='_blank' rel='noopener noreferrer')

模板基于本站卡片结构精简,使用 Pug 的属性和文本转义,避免把标题、描述重新拼成一大段 HTML。YAML 应由站主维护,外链仍须使用可信的 http/https 地址。

5. 添加样式

新建 source/static/css/collect-cards.css,添加下面的样式。如果之前改过这一块,记得先合并旧样式。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#article-june-collect .june-collect-list { display:flex; flex-wrap:wrap; gap:18px; }
#article-june-collect .june-collect_box {
width:calc(100% / 6 - 15px); aspect-ratio:3/4; position:relative;
display:flex; flex-direction:column; justify-content:space-between;
background-size:cover; background-position:center; background-color:#34495e;
border-radius:12px; overflow:hidden; padding:10px; color:#fff;
}
#article-june-collect .june-collect_box::after {
content:''; position:absolute; inset:0; background:#0005; pointer-events:none;
}
#article-june-collect .june-collect_top,
#article-june-collect .june-collect_content { position:relative; z-index:1; }
#article-june-collect .june-collect_content { pointer-events:none; }
#article-june-collect .june-collect_content > span { font-weight:bold; }
#article-june-collect .june-collect_content p { margin:4px 0; }
#article-june-collect .june-collect-div { position:absolute; inset:0; z-index:2; }
#article-june-collect .june-collect-a { display:block; width:100%; height:100%; }
@media(max-width:1000px) { #article-june-collect .june-collect_box { width:calc(100% / 4 - 14px); } }
@media(max-width:600px) { #article-june-collect .june-collect_box { width:calc(100% / 2 - 9px); } }

然后在 _config.butterfly.yml 的 inject.head 里引入:

1
2
3
inject:
head:
- <link rel="stylesheet" href="/static/css/collect-cards.css">

6. 书评弹窗

本站后面增加了 review 字段和书评弹窗,涉及 collect-review.js、弹窗 DOM 及额外样式。这里先做封面、星级、日期和外链,想加书评弹窗还需要配套的脚本和样式。

已有完整版页面时不要同时覆盖成本篇基础版。需要保留弹窗,应以源码中的 collect.pug、collect-review.js 和 _page/collect.styl 配套迁移。