2023-09-17: 删除1.4之前版本的支持,请更新到最新的 memos
2023-06-10: 支持使用资源库图片(无法设置时间和地点)
2023-02-03: 支持发送多条memos内容,只要标签是 #相册 即可。
更新简化部分代码,感谢@林木木大佬提供safari报错的解决方案。

Hugo博客可以参考木木大佬的文章部署,也可以自行移植。

如果你没有服务器可以搭建memos,可以使用小N和杜老师维护的公益服务:memos纯公益代部署服务

前言

我一直都很想把相册做成动态的,因为每次我想传图片的时候都不在电脑身边,每次在电脑身边都会忘了传图片。这就很不友好。

就在前些天木木大佬竟然发了相关的文章:Hugo 添加相册页面
这不是渴了有人递水困了有人递枕头嘛,省得自己再费大劲写了。感谢木木大佬!

我是先看了一下bf自带的gallery。可以实现,但是有一点BUG。研究了很久也没解决它,而且还无法自定义dom结构。
于是便选择移植一下木木大佬的代码,通过memos来实现动态相册。

教程

引入文件

我直接放的木木大佬的js地址,建议下载下面的文件放到自己的js文件夹内。

1
2
3
4
5
6
7
8
# waterfall
- <script defer src="https://immmmm.com/waterfall.min.js"></script>
# imgStatus
- <script defer src="https://immmmm.com/imgStatus.min.js"></script>
# lately
- <script defer src="https://immmmm.com/lately.min.js"></script>
# 自定义js一定要放在最下面
- <script defer src="/js/xxxx.js?v1"></script>

页面内代码

新建相册页面,粘贴如下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
---
title: 我的生活
date: 2022-06-28 21:15:13
updated:
type:
aside: false
comments: false
description:
keywords:
top_img:
mathjax:
katex:
aplayer:
highlight_shrink:
---

<!-- 复制以下内容,上方内容是为了避免一些人看不懂放在哪 -->
<div class="gallery-photos page">
<img src="/img/loading.svg" style="margin:auto">
</div>

<style>
#article-container a img {margin: 0; border-radius:0;}
.gallery-photos{width:100%;margin-top: 10px;}
.gallery-photo{min-height:5rem;width:24.97%;padding:4px;position: relative;}
.gallery-photo a{border-radius:8px;display:block;overflow: hidden;}
.gallery-photo img{display: block;width:100%;animation: fadeIn 1s;cursor: pointer;transition: all .4s ease-in-out !important;}
.gallery-photo span.photo-title,.gallery-photo span.photo-time{max-width: calc(100% - 7px);line-height:1.8;position:absolute;left:4px;font-size:14px;background: rgba(0, 0, 0, 0.3);padding:0px 8px;color: #fff;animation: fadeIn 1s;}
.gallery-photo span.photo-title{bottom:4px;border-radius: 0 8px 0 8px;}
.gallery-photo span.photo-time{top:4px;border-radius: 8px 0 8px 0;}
.gallery-photo:hover img{transform: scale(1.1);}
@media screen and (max-width: 1100px) {.gallery-photo{width:33.3%;}}
@media screen and (max-width: 768px) {
.gallery-photo{width:49.9%;padding:3px}
.gallery-photo span.photo-time{display:none}
.gallery-photo span.photo-title{font-size:12px}
.gallery-photo span.photo-title{left:3px;bottom:3px;}
}
@keyframes fadeIn{0% {opacity: 0;}100%{opacity: 1;}}
</style>

获取api

memos api地址格式如下:
https://memos地址/api/v1/memo?creatorId=用户ID&tag=标签名&limit=限制数量

其中memos地址就是首页地址,如:m.leonus.cn
用户ID的获取方法如下:

  1. 点击个人头像,然后点击 RSS。
  2. 根据连接获取ID
    如 RSS 链接为:https://m.leonus.cn/u/`1`/rss.xml
    则creatorId就是1

最后完整链接如下:
https://m.leonus.cn/api/v1/memo?creatorId=1&tag=说说&limit=10

自定义js

自定义js插入如下内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
// 适配pjax
function whenDOMReady() {
if (location.pathname == '/photos/') photos();
}
whenDOMReady()
document.addEventListener("pjax:complete", whenDOMReady)

// 自适应
window.onresize = () => {
if (location.pathname == '/photos/') waterfall('.gallery-photos');
};

// 函数 以下为23-06-10更新区域
function photos() {
let url = 'https://m.leonus.cn' // 修改api
fetch(url + '/api/v1/memo?creatorId=1&tag=相册').then(res => res.json()).then(data => {
let html = '',
imgs = []
data.forEach(item => {
let ls = item.content.match(/\!\[.*?\]\(.*?\)/g)
if (ls) imgs = imgs.concat(ls)
if (item.resourceList.length) {
item.resourceList.forEach(t => {
if (t.externalLink) imgs.push(`![](${t.externalLink})`)
else imgs.push(`![](${url}/o/r/${t.id}/${t.publicId}/${t.filename})`)
})
}
})

if (imgs) imgs.forEach(item => {
let img = item.replace(/!\[.*?\]\((.*?)\)/g, '$1'),
time, title, tat = item.replace(/!\[(.*?)\]\(.*?\)/g, '$1')
if (tat.indexOf(' ') != -1) {
time = tat.split(' ')[0]
title = tat.split(' ')[1]
} else title = tat

html += `<div class="gallery-photo"><a href="${img}" data-fancybox="gallery" class="fancybox" data-thumb="${img}"><img class="no-lazyload photo-img" loading='lazy' decoding="async" src="${img}"></a>`
title ? html += `<span class="photo-title">${title}</span>` : ''
time ? html += `<span class="photo-time">${time}</span>` : ''
html += `</div>`
})

document.querySelector('.gallery-photos.page').innerHTML = html
imgStatus.watch('.photo-img', () => { waterfall('.gallery-photos') })
window.Lately && Lately.init({ target: '.photo-time' })
}).catch()
}

使用

在memos中使用如下格式即可:

1
2
3
4
5
6
7
8
9
#相册 
<!-- 写法就是markdown的写法,中括号里先写时间再写标题,中间使用空格隔开 -->
![2023-01-29 我是标题](图片链接)
<!-- 若不想要时间只写标题即可 -->
![我是标题](图片链接)
<!-- 若不想要标题只写时间即可,只不过后面需要添加空格 -->
![2023-01-29 ](图片链接)
<!-- 也可以只填写图片链接 -->
![](图片链接)

示例:

1
2
3
4
5
#相册 
![2023-01-29 ](https://cdn.leonus.cn/life/IMG20221009072832.webp)
![校园](https://cdn.leonus.cn/life/IMG20221009183315.webp)
![2023-01-29 校园](https://cdn.leonus.cn/life/IMG20221009071448.webp)
![](https://cdn.leonus.cn/life/faceu_-413_20221002094043836-tuya.webp)

显示效果如下:
示例

骚操作

因为在memos中图片会进行渲染,这样的话图片多了会占用很大的空间,上下翻看内容时很不友好。
而且本人认为在memos中这些图片没必要进行渲染,所以我们可以使用 代码块 来使这些图片不进行渲染(不会影响博客相册渲染)。效果如下:
使用代码块
未使用代码块