基于Zeabur部署Memos实现说说页面

前言

这几天一直想给博客增加一个说说页面,昨天尝试了用leancloud和artitalk成功部署了页面,但是由于我用的leancloud是国际版的(国内版的需要备案才能使用),所以在国内不用梯子我就加载不出说说页面。于是我就在网上寻找其他的办法,我发现许多人都在用memos,这个比起artitalk访问就快多了,而且也很美观,便想着也部署一个放在我的博客上。由于我在这方面完全是零基础,搭建期间遇到了不少问题,克服了重重困难后,我终于部署成功了。在此写下这篇文章期望能帮到其他和我一样的小白们。

本篇参考了下面两个大佬的教程

子虚栈的一分钟免费部署你的专属 Memos

Leonus的基于Momos实现说说和清单功能

创建Zeabur并部署Memos

这一步可以直接看子虚栈大佬的教程,已经写得很清楚了,一分钟免费部署你的专属 Memos

将Memos部署到博客中

部署页面

首先创建一个新页面,在博客根目录中执行

1
hexo new page talk(名字可以自定义)

然后记得在主题配置文件中的目录中增加你新创建的talk页面,这样才能在博客菜单中显示“talk”按钮

然后打开blog\source\talk\index.md

在里面增加以下代码(源自Leonus - 进一寸有进一寸的欢喜。))

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
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
<style>
/* 页面初始化 */
div#page {
background: none;
border: 0;
padding: 0;
}

[data-theme=dark] #twikoo .tk-content,
#twikoo .tk-content {
padding: 0;
background: transparent;
}

.talk_item,
.tk-expand,
.tk-comments-container>.tk-comment,
.tk-submit:nth-child(1){
background: var(--card-bg);
border: 1px solid #e0e3ed;
box-shadow: 0 5px 10px rgb(189 189 189 / 10%);
transition: all .3s ease-in-out;
border-radius: 12px;
}
.talk_item:hover,
.tk-comments-container>.tk-comment:hover,
.tk-submit:nth-child(1):hover {
border-color: #49b1f5;
}

.tk-submit {
padding: 20px 10px 0;
}

.tk-comments-container>.tk-comment {
padding: 15px;
}

/* 页面初始化结束 */

#talk{
margin-top: 1rem;
}

#talk .loading {
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
}

#talk .loading img {
width: 200px;
}

.talk_item {
display: flex;
flex-direction: column;
padding: 20px;
margin-bottom: 15px;
}

.avatar {
margin: 0 !important;
width: 60px;
height: 60px;
border-radius: 10px;
}


.talk_bottom,
.talk_meta {
display: flex;
align-items: center;
width: 100%;
line-height: 1.5;
}
.talk_bottom{
justify-content: space-between;
}
.info {
display: flex;
flex-direction: column;
margin-left: 10px;
}
span.talk_nick {
color: #6dbdc3;
font-size: 1.2rem;
}
svg.is-badge.icon {
width: 15px;
margin-left: 5px;
padding-top: 3px;
}
span.talk_date {
opacity: .6;
}

.talk_content {
line-height: 1.5;
margin-top: 10px;
}
.zone_imgbox {
display: flex;
flex-wrap: wrap;
--w: calc(25% - 8px);
gap: 10px;
margin-top: 5px;
}
.zone_imgbox a {
display: block;
border-radius: 12px;
width: var(--w);
aspect-ratio: 1/1;
position: relative;
}

.zone_imgbox img {
width: 100%;
height: 100%;
margin: 0 !important;
object-fit: cover;
}
/* 底部 */

.talk_bottom {
opacity: .9;
}
.talk_bottom .icon {
color: var(--font-color);
float: right;
transition: all .3s;
}

.talk_bottom .icon:hover {
color: #49b1f5;
}

span.talk_tag{
font-size: 14px;
}
.talk_content>a {
margin: 0 3px;
color: #ff7d73 !important;
}
.talk_content>a:hover{
text-decoration: none !important;
color: #ff5143 !important
}

/* 提醒 */

.limit {
transition: all .3s ease-in-out;
color: rgba(76, 73, 72, 0.6);
}

[data-theme=dark] .limit {
color: rgba(255, 255, 255, 0.5);
}

.limit {
display: none;
text-align: center;
margin-top: 20px;
color: var(--font-color);
}
@media screen and (max-width: 900px) {
.zone_imgbox {
--w: calc(33% - 5px);
}
#talk{
margin: 10px 3px 0
}
#post-comment{
margin: 0 3px
}
}

@media screen and (max-width: 768px) {
.zone_imgbox {
gap: 6px;
}
.zone_imgbox {
--w: calc(50% - 3px);
}
span.talk_date {
font-size: 14px;
}
}
</style>

<div id="talk">
<div class='loading'><img src="/img/loading.svg" alt="加载中..."></div>
</div>

<div class="limit">- 只展示最近30条说说 -</div>
<script>
if(1) {
let url = 'https://你的memos地址'//这里地址最后面不要有'/'

fetch(url + '/api/v1/memo?creatorId=你的ID&tag=说说&limit=30').then(res => res.json()).then(data => { // 注意修改"你的ID"
let items = [],
html = '',
icon = '<svg viewBox="0 0 512 512"xmlns="http://www.w3.org/2000/svg"class="is-badge icon"><path d="m512 268c0 17.9-4.3 34.5-12.9 49.7s-20.1 27.1-34.6 35.4c.4 2.7.6 6.9.6 12.6 0 27.1-9.1 50.1-27.1 69.1-18.1 19.1-39.9 28.6-65.4 28.6-11.4 0-22.3-2.1-32.6-6.3-8 16.4-19.5 29.6-34.6 39.7-15 10.2-31.5 15.2-49.4 15.2-18.3 0-34.9-4.9-49.7-14.9-14.9-9.9-26.3-23.2-34.3-40-10.3 4.2-21.1 6.3-32.6 6.3-25.5 0-47.4-9.5-65.7-28.6-18.3-19-27.4-42.1-27.4-69.1 0-3 .4-7.2 1.1-12.6-14.5-8.4-26-20.2-34.6-35.4-8.5-15.2-12.8-31.8-12.8-49.7 0-19 4.8-36.5 14.3-52.3s22.3-27.5 38.3-35.1c-4.2-11.4-6.3-22.9-6.3-34.3 0-27 9.1-50.1 27.4-69.1s40.2-28.6 65.7-28.6c11.4 0 22.3 2.1 32.6 6.3 8-16.4 19.5-29.6 34.6-39.7 15-10.1 31.5-15.2 49.4-15.2s34.4 5.1 49.4 15.1c15 10.1 26.6 23.3 34.6 39.7 10.3-4.2 21.1-6.3 32.6-6.3 25.5 0 47.3 9.5 65.4 28.6s27.1 42.1 27.1 69.1c0 12.6-1.9 24-5.7 34.3 16 7.6 28.8 19.3 38.3 35.1 9.5 15.9 14.3 33.4 14.3 52.4zm-266.9 77.1 105.7-158.3c2.7-4.2 3.5-8.8 2.6-13.7-1-4.9-3.5-8.8-7.7-11.4-4.2-2.7-8.8-3.6-13.7-2.9-5 .8-9 3.2-12 7.4l-93.1 140-42.9-42.8c-3.8-3.8-8.2-5.6-13.1-5.4-5 .2-9.3 2-13.1 5.4-3.4 3.4-5.1 7.7-5.1 12.9 0 5.1 1.7 9.4 5.1 12.9l58.9 58.9 2.9 2.3c3.4 2.3 6.9 3.4 10.3 3.4 6.7-.1 11.8-2.9 15.2-8.7z"fill="#1da1f2"></path></svg>';

data.forEach(item => { items.push(Format(item)) });
if (items.length == 30) document.querySelector('.limit').style.display = 'block';
items.forEach(item => {
html += `<div class="talk_item"><div class="talk_meta"><img class="no-lightbox no-lazyload avatar" src="这里是你头像链接"><span class="talk_nick">名称${icon}</span><span class="talk_date">${item.date}</span></div></div><div class="talk_content">${item.content}</div><div class="talk_bottom"><div><span class="talk_tag"># ${item.tag}</span></div><a href="javascript:;"onclick="goComment('${item.text}')"><span class="icon"><i class="fa-solid fa-message fa-fw"></i></span></a></div></div>` // 注意修改头像链接和名称(直接替换掉)
})
document.getElementById('talk').innerHTML = html
})
// 页面评论
function goComment(e) {
var n = document.querySelector(".el-textarea__inner")
n.value = `> ${e}\n\n`;
n.focus();
btf.snackbarShow("无需删除空行,直接输入评论即可", !1, 2e3);
}
// 页面内容格式化
function Format(item) {
let date = getTime(new Date(item.createdTs * 1000).toString()),
content = item.content,
tag = item.content.match(/\{(.*?)\}/g),
imgs = content.match(/!\[.*\]\(.*?\)/g),
text = ''
if (imgs) imgs = imgs.map(item => { return item.replace(/!\[.*\]\((.*?)\)/, '$1') })
if (item.resourceList.length) {
if (!imgs) imgs = []
item.resourceList.forEach(t => {
if (t.externalLink) imgs.push(t.externalLink)
else imgs.push(`${url}/o/r/${t.id}/${t.publicId}/${t.filename}`)
})
}
text = content.replace(/#(.*?)\s/g, '').replace(/\!\[(.*?)\]\((.*?)\)/g, '').replace(/\{(.*?)\}/g, '')
content = text.replace(/\[(.*?)\]\((.*?)\)/g, `<a href="$2">@$1</a>`);
if (imgs) {
content += `<div class="zone_imgbox">`
imgs.forEach(e => content += `<a href="${e}" data-fancybox="gallery" class="fancybox" data-thumb="${e}"><img class="no-lazyload" src="${e}"></a>` // 2023-02-06更新
)
content += '</div>'
}
return {
content: content,
tag: tag ? tag[0].replace(/\{(.*?)\}/,'$1') : '无标签',
date: date,
text: text.replace(/\[(.*?)\]\((.*?)\)/g, '[链接]' + `${imgs?'[图片]':''}`)
}
}
// 页面时间格式化
function getTime(time) {
let d = new Date(time),
ls = [d.getFullYear(), d.getMonth() + 1, d.getDate(), d.getHours(), d.getMinutes(), d.getSeconds()];
for (let i = 0; i < ls.length; i++) {
ls[i] = ls[i] <= 9 ? '0' + ls[i] : ls[i] + ''
}
if (new Date().getFullYear() == ls[0]) return ls[1] + '月' + ls[2] + '日 ' + ls[3] +':'+ ls[4]
else return ls[0] + '年' + ls[1] + '月' + ls[2] + '日 ' + ls[3] +':'+ ls[4]
}
}
</script>

这里我将代码修改到了适配memos1.4.0以上版本的,如果你的memos版本在1.4.0一下,可以去原教程里找相应的代码,还有要注意的地方就是代码第200行粘贴你的memos地址时记得地址最后不要有‘/’符号

关于Memos用户ID

代码中有一处要修改成你自己的ID,我按照Leonus的教程中关于用户ID获取的方法操作之后,发现本该显示ID的地方显示成了我的用户名1

我原本以为这里的用户名就是我的id,但放到代码中提示是错误的,我在这里卡了好久,在我的一番摸索之下,我发现了一个新的获取id的方法:

点击memos的RSS

2

这里这url中u/后面的数字就是我们的ID

3

将你的ID放到代码中去,就能成功部署说说页面了

使用

在memos中,使用特定的格式,将发布范围设置为所有人可见,发布之后就可以在你的博客页面看到你发的内容了

1
#说说 {说说标签} 我是内容 [我是链接](链接地址) ![](图片链接)

4

更多

关于更多进阶用法,可以去看基于Momos实现说说和清单功能


基于Zeabur部署Memos实现说说页面
http://cdt3211.github.io/2023/08/20/基于Zeabur部署Memos实现说说页面/
作者
Abner
发布于
2023年8月20日
许可协议