在 上一篇关于Hexo的文章 之后,其中关于相册的功能一直没太能完全实现,暂时采用的是 HEXO博客搭建相册 的解决方案,但是没有子相册的功能。时隔将近一个月之后,自己在 Hexo NexT 主题下自己实现了自己想要的功能,大体能够满足我的需求,也许以后还会再改。这篇文章仅仅当做自己的记录,期待能够给其他人带来一些参考。
相册期待实现效果
对于相册,在自己 基于Hexo NexT搭建 的博客上期待实现与豆瓣相册类似的效果,具体如下
- 主界面
- 分类相册
- 自定义相册名
- 自定义封面
- 分类相册界面
- 三等分列
- 点击看大图
- 本地图片源/图床外链均可
- 与文章插图格式保持统一
- 其他
- 每张图片都可以有对应的文字描述
- 游客可以为图片添加评论
- 相册里面也可以插入视频
目前可查到的方案
- Hexo NexT主题内添加相册功能 没有子相册功能,流程不够自动化
- css+markdown 实现 hexo 相册 纯css的实现,没有photoswipe的效果,不够动态
- HEXO博客搭建相册 没有子相册功能
- hexo博客添加一级分类相册功能 使用的不是Next主题
自己也到Hexo NexT的github社区问过大家的意见。确实作为相册这个功能,每个人都有自己独特的需求,如果能够开发成专门的插件似乎是一个更好的选择。(也许以后可以再填一填坑?现在确实还没太有时间来搞这个)
我的实现方案
我的方案基本上是 hexo博客添加一级分类相册功能 和 HEXO博客搭建相册 两篇文章方法的综合体。具体如下
一级分类相册 Album
一级分类相册需要有自己专门的页面,我们可以自己定制Album的页面,然后Hexo就会基于模板渲染出对应的html页面。这里只是根据配置,在Album页面加入了各个gallery的封面,相册名和相册描述。根据需要,你也可以添加更新时间,相册的图片数量等信息。
1 | {% extends '_layout.swig' %} |
在渲染的时候,我们需要用到站点配置文件中的一些参数。比如到底有多少相册,每个相册的名字是什么,封面的图片是什么,相册的描述怎样。这里需要在站点配置文件中添加如下:
1 | album: |
对于Album页面,这里只是生成了html页面,你可以根据css来定制对应的样式。这里我的css数据放在了blog/souce/_data/styles.styl
中,这里放置了我所有的自定义的样式。
1 | .gallery-wrapper{ |
有了这些模板之后,只需要在blog/souce
目录下创建album目录,在目录下创建对应的index.md即可
1 | --- |
二级相册 Gallery
可以看到,在Album页面,每一个二级相册Gallery都可以通过点击封面作为一个链接访问。访问请求是/album/<gallery-name>
。
Gallery页面描述文件
因此,我们在Album目录下,为每一个Gallery创建子目录,比如这里的Period
和 Cosmos
。类似的我们为gallery创建了一个渲染模板,在Period目录下,我们只需要有对应的 index.md
和 描述gallery的JSON文件即可。
1 | --- |
下面是描述相册的JSON文件,你可以通过Python脚本自动生成和更新。
1 | { |
Gallery页面样式
接下来是layout下面的gallery.swig
文件
1 | {% extends '_layout.swig' %} |
其实到这一步已经和 HEXO博客搭建相册 里面说的很像了。只是我把这些给模板化了,同时修改了JSON文件的数据格式。
Gallery页面JS脚本
然后接下来就是修改gallery.js
了,不知道写前端的人代码风格怎么样,原来的gallery.js
(也就是之前教程里面的ins.js
)代码让我看起来感觉不是很清晰。原来相关代码比较长,也不是原生手写的代码,而是通过webpack
自动打包生成的代码。因此学习了一下前端技术中的webpack
,下面具体梳理一下相关脚本的逻辑思路。
webpack打包环境
关于webpack,可以参考教程
主机系统上安装的webpack版本是4.41.2,关于文件组织结构如下
1 | ╭─ houmin@cosmos ~/blog/album_script master |
其中,webpack.config.js
代码如下:
1 | const path = require('path'); |
可以看到,webpack的大包入口文件是gallery.js
gallery文件
1 | ; |
可以看到,这里的gallery.js
依赖了 lazyloadjs
和 photoswipe.js
, 整个文件的思路非常直接
- 初始化
Gallery
对象,它会在初始化的时候通过XHR请求打开对应Gallery的JSON描述文件 - 获取JSON文件的响应后,通过render函数来解析JSON数据,从而拼接处对应的HTML文本
- 这里具体的相册名是通过解析访问的链接名得到的
window.location.pathname
- 为了能够使用
photoswipe
插件,我们需要在render函数中讲view
对象初始化
关于 lazyloadjs
插件的使用,可以参考 其GitHub说明文档
photoswipe文件
这里的 photoswipe.js
主要参考了photoswipe官方文档的 How to build an array of slides from a list of links 部分。
主要的思想就是,根据上面 gallery.js
中生成的链接的list,利用photoswipe生成对应的photoswipe对象。
1 | ; |
自动化更新JSON脚本
这里补上了自动化上传图片的脚本。脚本的功能如下
- 创建相册
- 插入图片
- 裁剪图片
- 压缩图片
- 更新JSON脚本
- 上传图片到AWS的S3服务
实现的原理很简单,由AlbumTool.py
和S3.py
组成。这两个文件放在hexo/album_tool
目录下,在同级路径还有一个album
的文件夹,针对不同的相册,都有artwork
、square
和thumbnail
三个文件夹。用户需要上传图片时,只需要将对应的图片放到artwork
路径下,然后运行python AlbumTool.py -a insert
就可以了,之后可以按照命令行的提示执行即可。
1 | #coding: utf-8 |
S3.py
主要是对boto3
进行了封装,配置好AWS的密钥信息之后,可以直接执行这个脚本。如果以后改用阿里云或者其他云服务商的对象存储服务,随之更新即可。
1 | import logging |
实际实现效果
大家可以到 我的相册 页面看看的实际的效果。基本上实现了上述的要求,欢迎评论。