Hexo anzhiyu 主题深度定制系列(五):相册系统全解析 —— Type 1/2/3 三种布局 + Pixiv 专辑实战

AI-摘要
Yoki AI
AI初始化中...
介绍自己 🙈
生成本文简介 👋
推荐相关文章 📖
前往主页 🏠
前往爱发电购买
Hexo anzhiyu 主题深度定制系列(五):相册系统全解析 —— Type 1/2/3 三种布局 + Pixiv 专辑实战
Yoki前言
anzhiyu 的相册功能不是简单的「图片列表」,而是一套 数据驱动 + 多布局 + 详情页 的完整体系。本文从 album.yml 数据源出发,追踪到 album.pug / album_detail.pug 模板,再到前端交互,最后演示如何新增一个 Pixiv 专辑。
1. 数据源:source/_data/album.yml
1 | # 相册列表页数据源,每一项 = 一个相册入口 |
1.1 字段完整对照表
| 字段 | 必填 | 类型 | 说明 |
|---|---|---|---|
name |
✅ | string | 相册名,列表卡片标题 |
description |
string | 列表卡片副标题 | |
type |
✅ | 1/2/3 | 1=瀑布流、2=画廊(分组轮播)、3=时间轴 |
photos |
✅ | array | 图片数据,结构随 type 变化 |
cover |
string | 列表卡片封面图(缺失则取 photos[0].url) |
1.2 photos 结构随 type 变化
type |
photos 结构 |
备注 |
|---|---|---|
| 1 | [{url, alt}] |
扁平数组,直接渲染网格 |
| 2 | [{group, photos:[{url,alt}]}] |
分组,每组一个 Swiper 实例 |
| 3 | [{date, photos:[{url,alt}]}] |
按日期分组,时间轴样式 |
2. 列表页模板:themes/anzhiyu/layout/includes/page/album.pug
1 | // album.pug 简化版 |
关键点:
data-type传给详情页,决定渲染哪套布局getAlbumCount(album)统计总图片数(含分组内)- 封面兜底逻辑:
cover→photos[0].photos[0].url(type2) →photos[0].url(type1)
3. 详情页模板:themes/anzhiyu/layout/includes/page/album_detail.pug
3.1 入口判断
1 | - const album = site.data.album.find(a => a.name === page.albumName) |
3.2 Type 1:瀑布流网格 (album_type1.pug)
1 | .waterfall#waterfall |
- CSS Columns 实现瀑布流:
column-count: 3; column-gap: 12px; fancybox绑定同一data-fancybox="album",点击可左右翻阅全相册- 懒加载
data-src+IntersectionObserver
3.3 Type 2:画廊轮播 (album_type2.pug)
1 | .gallery-album |
前端初始化(main.js 片段):
1 | document.querySelectorAll('.gallery-swiper').forEach((el, i) => { |
- Tab 切换 = 显示/隐藏对应
.gallery-swiper - 每组独立
data-fancybox="gallery_原神",组内可翻阅,组间隔离
3.4 Type 3:时间轴 (album_type3.pug)
1 | .timeline-album |
- 适合「旅行日记」「成长记录」等按时间叙事的相册
4. 页面入口:source/album/index.md
1 | --- |
Hexo 会把 site.data.album 注入页面,album.pug 自动渲染列表。
5. 实战:新增 Pixiv 专辑
5.1 数据追加(source/_data/album.yml)
1 | - name: Pixiv |
5.2 可选:独立详情页(source/pixiv/index.md)
1 | --- |
区别:
type: album= 列表页;type: album_detail+album: 名称= 直达某相册详情页。
5.3 导航菜单挂载(_config.anzhiyu.yml)
1 | menu: |
6. 图片托管与性能建议
| 方案 | 适用场景 | 成本 |
|---|---|---|
| 自建图床 + Cloudflare R2 / Backblaze B2 + CDN | 全量控制、大流量 | 低(按量付费) |
| GitHub + jsDelivr | 小站、图片 < 50MB/仓库 | 免费 |
| PicGo + 阿里云 OSS / 腾讯云 COS | 国内访问快、备案域名 | 低 |
| Cloudflare Images | 自动 WebP/AVIF、变体、统计 | $5/10万张/月 |
推荐工作流:
1 | 本地选图 → PicGo 一键上传 → 返回 CDN URL → 粘贴 album.yml |
性能清单:
- 所有图片 WebP/AVIF 输出(Cloudflare Images / imgproxy 自动转码)
-
loading=lazy+decoding=async(模板已内置) - 列表页封面 低质量占位图 (LQIP) →
blur-up动画 - 详情页
fancybox预加载相邻 1 张 - 相册总大小 > 50MB 考虑 分页/虚拟列表
7. 扩展玩法
7.1 相册加密(私密相册)
1 | # album.yml |
前端 album_detail.pug 判断 encrypted → 弹窗输入密码 → bcrypt.compare → 通过后渲染。
7.2 EXIF 信息展示
1 | // album_type1.pug |
上传脚本用 exifr 读取写入 album.yml。
7.3 相册统计卡片
1 | // album.pug 列表卡片底部 |
8. 常见坑 & 调试
| 现象 | 原因 | 解决 |
|---|---|---|
| 详情页 404 | album.yml 的 name 与页面 album: 不一致 |
严格对应,含大小写、空格 |
| 画廊 Tab 切换无反应 | Swiper 实例未销毁重建 / display:none 下初始化宽度为 0 |
Tab 切换时 swiper.update() 或 lazy: true |
| 瀑布流高度塌陷 | img 无 width/height 导致 columns 计算错误 |
图片加上 style="aspect-ratio: 4/3" 或 CSS aspect-ratio |
fancybox 不能翻阅全相册 |
data-fancybox 值不一致 |
同一相册所有图片 data-fancybox="album_相册名" 统一 |
9. 小结
| 布局 | 适用场景 | 核心技术 |
|---|---|---|
| Type 1 瀑布流 | 风景、壁纸、大量同权重图片 | CSS Columns + Fancybox |
| Type 2 画廊 | 分类明确、需分组轮播(如 Pixiv、cosplay) | Swiper + Tab + Fancybox 分组 |
| Type 3 时间轴 | 旅行、成长记录、按时间叙事 | 垂直时间轴 + Fancybox |
数据驱动 = 只改 album.yml,零代码新增相册;
模板分发 = album_detail.pug 统一入口,include 子模板,维护成本极低。
10. 下一篇预告
《友链页顶部区块 + 底部版权栏 + 音乐页/时钟/代码注入等杂项配置》
敬请期待!
评论
匿名评论隐私政策
TwikooWaline
✅ 你无需删除空行,直接评论以获取最佳展示效果




